mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-01-09 13:33:26 +00:00
First working LISP parser
This commit is contained in:
parent
b8d300f9f9
commit
0baad05c04
@ -23,7 +23,8 @@ struc t_sym
|
|||||||
char[0] name
|
char[0] name
|
||||||
end
|
end
|
||||||
|
|
||||||
predef print(s_expr)#0
|
predef parse_expr(evalptr, depth)#2
|
||||||
|
predef print(s_expr)
|
||||||
|
|
||||||
def new_cons
|
def new_cons
|
||||||
var consptr
|
var consptr
|
||||||
@ -86,6 +87,24 @@ def parse_sym(evalptr)#2 // return evalptr, symptr
|
|||||||
return evalptr, new_sym(symptr, evalptr - symptr)
|
return evalptr, new_sym(symptr, evalptr - symptr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_elem(evalptr, depth)#2 // return evalptr, exprptr
|
||||||
|
var elemptr
|
||||||
|
|
||||||
|
if ^evalptr == '('
|
||||||
|
evalptr++
|
||||||
|
evalptr, elemptr = parse_expr(evalptr, depth + 1)
|
||||||
|
elsif (^evalptr == '-' and is_num(^(evalptr+1))) or is_num(^evalptr)
|
||||||
|
evalptr, elemptr = parse_num(evalptr)
|
||||||
|
elsif is_alphasym(^evalptr)
|
||||||
|
evalptr, elemptr = parse_sym(evalptr)
|
||||||
|
else
|
||||||
|
putc('\\')
|
||||||
|
putc(^evalptr)
|
||||||
|
evalptr++
|
||||||
|
fin
|
||||||
|
return evalptr, elemptr
|
||||||
|
end
|
||||||
|
|
||||||
def parse_expr(evalptr, depth)#2 // return evalptr, exprptr
|
def parse_expr(evalptr, depth)#2 // return evalptr, exprptr
|
||||||
var exprptr, consptr, elemptr
|
var exprptr, consptr, elemptr
|
||||||
|
|
||||||
@ -112,27 +131,33 @@ def parse_expr(evalptr, depth)#2 // return evalptr, exprptr
|
|||||||
is ' '
|
is ' '
|
||||||
evalptr++
|
evalptr++
|
||||||
break
|
break
|
||||||
is '('
|
|
||||||
evalptr++
|
|
||||||
evalptr, elemptr = parse_expr(evalptr, depth + 1)
|
|
||||||
break
|
|
||||||
is ')'
|
is ')'
|
||||||
putln
|
putln
|
||||||
return evalptr, exprptr
|
return evalptr + 1, exprptr
|
||||||
otherwise
|
is '('
|
||||||
|
evalptr++
|
||||||
if depth == 0
|
if depth == 0
|
||||||
puts("Invalid S-Expression\n")
|
depth++
|
||||||
^evalptr = 0
|
else
|
||||||
|
evalptr, elemptr = parse_expr(evalptr, depth + 1)
|
||||||
|
fin
|
||||||
|
break
|
||||||
|
is '.'
|
||||||
|
evalptr++
|
||||||
|
evalptr, elemptr = parse_expr(evalptr, 0)
|
||||||
|
//
|
||||||
|
// Add expression to CDR
|
||||||
|
//
|
||||||
|
if not (consptr and consptr=>car)
|
||||||
|
puts("Invalid . operator\n")
|
||||||
return evalptr, NULL
|
return evalptr, NULL
|
||||||
fin
|
fin
|
||||||
if (^evalptr == '-' and is_num(^(evalptr+1))) or is_num(^evalptr)
|
consptr=>cdr = elemptr
|
||||||
evalptr, elemptr = parse_num(evalptr)
|
return evalptr, exprptr
|
||||||
elsif is_alphasym(^evalptr)
|
otherwise
|
||||||
evalptr, elemptr = parse_sym(evalptr)
|
evalptr, elemptr = parse_elem(evalptr, depth)
|
||||||
else
|
if depth == 0
|
||||||
putc('\\')
|
return evalptr, elemptr
|
||||||
putc(^evalptr)
|
|
||||||
evalptr++
|
|
||||||
fin
|
fin
|
||||||
wend
|
wend
|
||||||
if elemptr
|
if elemptr
|
||||||
@ -140,15 +165,13 @@ def parse_expr(evalptr, depth)#2 // return evalptr, exprptr
|
|||||||
// Add element to S-expression
|
// Add element to S-expression
|
||||||
//
|
//
|
||||||
if not consptr
|
if not consptr
|
||||||
consptr = elemptr
|
consptr = new_cons
|
||||||
exprptr = consptr
|
exprptr = consptr
|
||||||
else
|
else
|
||||||
if consptr=>car
|
consptr=>cdr = new_cons
|
||||||
consptr=>cdr = new_cons
|
consptr = consptr=>cdr
|
||||||
consptr = consptr=>cdr
|
|
||||||
fin
|
|
||||||
consptr=>car = elemptr
|
|
||||||
fin
|
fin
|
||||||
|
consptr=>car = elemptr
|
||||||
fin
|
fin
|
||||||
loop
|
loop
|
||||||
return evalptr, exprptr
|
return evalptr, exprptr
|
||||||
@ -173,37 +196,39 @@ end
|
|||||||
def print_elem(s_expr)#0
|
def print_elem(s_expr)#0
|
||||||
byte t
|
byte t
|
||||||
|
|
||||||
when s_expr->type & TYPE_MASK
|
if not s_expr
|
||||||
is CONS_TYPE
|
puts("NIL")
|
||||||
print(s_expr)
|
else
|
||||||
break
|
when s_expr->type & TYPE_MASK
|
||||||
is NUM_TYPE
|
is CONS_TYPE
|
||||||
puti(s_expr=>val)
|
print(s_expr)
|
||||||
break
|
break
|
||||||
is SYM_TYPE
|
is NUM_TYPE
|
||||||
t = s_expr->type
|
puti(s_expr=>val)
|
||||||
s_expr->type = t & SYM_LEN
|
break
|
||||||
puts(s_expr + type)
|
is SYM_TYPE
|
||||||
s_expr->type = t
|
t = s_expr->type
|
||||||
break;
|
s_expr->type = t & SYM_LEN
|
||||||
is NULL
|
puts(s_expr + type)
|
||||||
puts("NIL")
|
s_expr->type = t
|
||||||
wend
|
break;
|
||||||
|
wend
|
||||||
|
fin
|
||||||
end
|
end
|
||||||
|
|
||||||
def print(s_expr)#0
|
def print(s_expr)
|
||||||
putc('(')
|
if not s_expr; return FALSE; fin
|
||||||
while s_expr
|
if s_expr->type == CONS_TYPE
|
||||||
if s_expr->type == CONS_TYPE
|
putc('(')
|
||||||
print_elem(s_expr=>car)
|
print_elem(s_expr=>car)
|
||||||
s_expr = s_expr=>cdr
|
putc('.')
|
||||||
else
|
print_elem(s_expr=>cdr)
|
||||||
print_elem(s_expr)
|
putc(')')
|
||||||
s_expr = NULL
|
else
|
||||||
fin
|
print_elem(s_expr)
|
||||||
loop
|
fin
|
||||||
putc(')')
|
return TRUE
|
||||||
end
|
end
|
||||||
|
|
||||||
while print(eval(read)); loop
|
while print(eval(read)); putln; loop
|
||||||
done
|
done
|
||||||
|
Loading…
x
Reference in New Issue
Block a user