On Sun, Apr 12, 2020 at 08:09:46AM +0200, Tomas Hlavaty wrote: > Rowan Thorpe <ro...@rowanthorpe.com> writes: > > parentheses are not used because as is stated at > > https://picolisp.com/wiki/?src64 "Assembly language is not a > > functional language, i.e. the individual instructions do not "return" > > a value. So a fully parenthesized syntax is useless and just tedious." > > because picolisp doesn't have a compiler (program) > > it is "compiled" to the picolisp assembly manually ahead of time by Alex > (human)
Actually, all this will change with the new PicoLisp "pil21". It is no longer oriented to machine *instructions* like pil64, but to SSA (Static Single Assignment) *values*. It is a radically different approach. If there is interest, work in progress can be seen at https://git.envs.net/mpech/pil21 or directly in https://software-lab.de/pil21.tgz Here the sources have real PicoLisp syntax (though partially different semantics). The compiler (in "src/lib/llvm.l") does not only use the reader, but generates the LLVM-IR by *executing* the code (Forth is chuckling from behind). This works by simply redefining some (not many) functions in llvm' and 'priv' namespaces. For example, the source of the 'car' function: In pil64 it is (in "src64/subr.l") # (car 'var) -> any (code 'doCar 2) push X ld X E ld E ((E CDR)) # Get arg eval num E # Need variable jnz varErrEX ld E (E) # Take CAR pop X ret This results in e.g. AMD/Intel asssembly (in "src64/x86-64.linux.base.s") .globl doCar doCar: push %r13 mov %rbx, %r13 mov 8(%rbx), %r10 mov (%r10), %rbx test $0x06, %bl jnz 1f test $0x08, %bl cmovnzq (%rbx), %rbx jnz 1f call evListE_E 1: testb $0x06, %bl jnz varErrEX mov (%rbx), %rbx pop %r13 ret Now in pil21 the source is (in "src/subr.l"): # (car 'var) -> any (de _car (Exe) (car (needVar Exe (eval (cadr Exe)))) ) and the result in LLVM-IR is (in "src/base.ll"): define i64 @_car(i64) { $1: ; # (cadr Exe) %1 = inttoptr i64 %0 to i64* %2 = getelementptr i64, i64* %1, i32 1 %3 = load i64, i64* %2 %4 = inttoptr i64 %3 to i64* %5 = load i64, i64* %4 ; # (eval (cadr Exe)) %6 = and i64 %5, 6 %7 = icmp ne i64 %6, 0 br i1 %7, label %$4, label %$3 $4: br label %$2 $3: %8 = and i64 %5, 8 %9 = icmp ne i64 %8, 0 br i1 %9, label %$6, label %$5 $6: %10 = inttoptr i64 %5 to i64* %11 = load i64, i64* %10 br label %$2 $5: %12 = call i64 @evList(i64 %5) br label %$2 $2: %13 = phi i64 [%5, %$4], [%11, %$6], [%12, %$5] ; # -> ; # (needVar Exe (eval (cadr Exe))) %14 = and i64 %13, 6 %15 = icmp ne i64 %14, 0 br i1 %15, label %$7, label %$8 $7: call void @varErr(i64 %0, i64 %13) unreachable $8: ; # (car (needVar Exe (eval (cadr Exe)))) %16 = inttoptr i64 %13 to i64* %17 = load i64, i64* %16 ret i64 %17 } Looks unbelievably horrible, but works ;) ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe