1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
OMGB $ is_digit ch is_alpha ch is_alnum ch4 read_number src i; read_binary src ic
read_ident src i� tokenize src� parse source
parse_program tokens i parse_statement tokens i@ parse_block tokens i� parse_expression tokens i( parse_or tokens i, parse_and tokens ig parse_comparison tokens i�
parse_add_sub tokens iS
parse_term tokens i� parse_shift tokens ib
parse_bit_and tokens i�
parse_bit_xor tokens i� parse_bit_or tokens i1
parse_factor tokens il
lookup_var env nameR
env_set env name value�
copy_env env�
normalize_path path�
dirname path join_path base rel. strip_header source path
call_function func_name func
arg_values env�
import_module path
eval_expr expr envD execute stmts env is_global� run source� run_file_with_args path file_args run_file pathV Z tok_len
global_env . current_dir <stdin> module_file loaded_modules args! length args run_file" & ch 0 ch 9$$ ch a ch z ch A ch Z ch _$$ ch is_alpha ch is_digit$$ num c src! length n i n src i is_digit^ src i c num
c! ascii 0! ascii num i iB num i $$ num c src! length n i n src i 0 src i 1� src i c num c! ascii 0! ascii num i ij num i $$ s src! length n i n src i is_alnum� s src i s i i� s i $$ tokens n i c res word s src! length src_len src_len src src_len
� src
src src_len src_len� src_len src ; src ; src ; src o src m src g i i src_len src i
i i i src_len src i
i i i src_len src i c c c c
c
= i i c #Q i src_len src i
P i iA c : i src_len src i =r tokens n symbol := ' n n i i c :� tokens n symbol : ' n n i i c = i src_len src i =� tokens n symbol == ' n n i i c =� Unexpected character =." c ! i src_len src i =� tokens n symbol != ' n n i i c < i src_len src i =� tokens n symbol <= ' n n i i c > i src_len src i = tokens n symbol >= ' n n i i c < i src_len src i <2 tokens n symbol << ' n n i i c > i src_len src i >S tokens n symbol >> ' n n i i c / i src_len src i /i Unexpected / after /." c / i src_len src i *� i i i src_len src i *
src i /
� i i i i c ( c ) c { c } c , c + c - c * c / c % c < c > c [ c ] c & c | c ^ c ~ c .� tokens n symbol c ' n n i i c 0 i src_len src i b src i B+ i i src i read_binary res tokens n number res ' n n res i c is_digitC src i read_number res tokens n number res ' n n res i c "� i i s i src_len src i "
y src i \ src i nn s
s i ix s src i s i iM i i tokens n string s ' n n src i
read_ident res res word res i word alloc word emit word proc word return word if word else word elif word loop word break word and word or word facts word import word as word try word except� tokens n kw word ' n n word true� tokens n bool ' n n word false� tokens n bool ' n n tokens n ident word ' n n n tok_len tokens n eof ' tokens$$ source tokenize tokens tokens
parse_program res res $$ stmts i res res tok_len9 tokens res parse_statement res stmts res stmts% stmts res $$ tokens i t t kw t allocj tokens i name tokens i parse_expression res decl name res res $� t kw t emit� tokens i parse_expression res emit res res $� t kw t return� tokens i parse_expression res return res res $� t kw t break� break i $� t kw t loop� tokens i parse_expression res_cond tokens res_cond parse_block res_block loop res_cond res_block res_block $� t kw t if� tokens i parse_expression res_cond tokens res_cond parse_block res_then res_then j elifs res_elif res_block
else_block k pair j tok_len tokens j kw tokens j elif: tokens j parse_expression res_elif tokens res_elif parse_block res_block elifs res_elif res_block elifs res_block j
j tok_len tokens j kw tokens j else] tokens j parse_block res_block res_block
else_block res_block j] elifs! length k k z elifs k pair if pair pair
else_block
else_block k kb if res_cond res_then
else_block j $� t kw t proc� tokens i name i j params tokens j symbol
tokens j )
� � params tokens j params j j tokens j symbol tokens j ,� j j� � � � j j tokens j parse_block res_block func_def name params res_block res_block $� t kw t import tokens i path tokens i alias import path alias i $� t kw t facts0 tokens i parse_expression res facts res res $� t kw t try� tokens i parse_block try_res try_res j tokens j kw tokens j except� j j name tokens j idento tokens j name j jo tokens j parse_block exc_res try try_res name exc_res exc_res $� � tokens i parse_factor lval_res lval_res j j tok_len tokens j symbol tokens j :=� tokens j parse_expression val_res lval_res target target ident� assign target val_res val_res $� target dot� attr_assign target target val_res val_res $� target index� index_assign target target val_res val_res $� � lval_res lval_res $$ stmts i j res j j tokens j symbol
tokens j }
! tokens j parse_statement res stmts res stmts res j stmts j $$ tokens i parse_or$ tokens i parse_and res res left res j right_res j tok_len tokens j kw tokens j orb tokens j parse_and right_res or left right_res left right_res j< left j $$ tokens i parse_comparison res res left res j right_res j tok_len tokens j kw tokens j and� tokens j parse_comparison right_res and left right_res left right_res jw left j $$ tokens i parse_bit_or res res left res j op right_res j tok_len tokens j symbol tokens j < tokens j == tokens j > tokens j <= tokens j >= tokens j !=N tokens j op tokens j parse_bit_or right_res op <
lt left right_res leftI op > gt left right_res leftI op <=& le left right_res leftI op >=4 ge left right_res leftI op ==B eq left right_res leftI ne left right_res left right_res j� left j $$ tokens i
parse_term res res left res j op right_res j tok_len tokens j symbol tokens j + tokens j -� tokens j op tokens j symbol tokens j + tokens j -� op + tokens j -� # Unexpected - after + unary operator."� op - tokens j +� # Unexpected + after - unary operator."� � tokens j
parse_term right_res op +� add left right_res left� sub left right_res left right_res jg left j $$ tokens i parse_factor res res left res j op right_res j tok_len tokens j symbol tokens j * tokens j / tokens j %] tokens j op tokens j parse_factor right_res op *C mul left right_res leftX op /Q div left right_res leftX mod left right_res left right_res j left j $$ tokens i
parse_add_sub res res left res j op right_res j tok_len tokens j symbol tokens j << tokens j >>� tokens j op tokens j
parse_add_sub right_res op <<� shl left right_res left� shr left right_res left right_res jv left j $$ tokens i parse_shift res res left res j right_res j tok_len tokens j symbol tokens j &� tokens j parse_shift right_res band left right_res left right_res j� left j $$ tokens i
parse_bit_and res res left res j right_res j tok_len tokens j symbol tokens j ^,
tokens j
parse_bit_and right_res bxor left right_res left right_res j
left j $$ tokens i
parse_bit_xor res res left res j right_res j tok_len tokens j symbol tokens j |g
tokens j
parse_bit_xor right_res bor left right_res left right_res jA
left j $$ tokens i t node i j k res t symbol t +�
tokens i symbol tokens i -�
# Unexpected - after + unary operator."�
tokens i parse_factor res unary add res res $\ t symbol t -�
tokens i symbol tokens i +�
# Unexpected + after - unary operator."�
tokens i parse_factor res unary sub res res $\ t symbol t ~ tokens i parse_factor res bitnot res res $\ t number number t node i j\ t bool% bool t node i j\ t string6 string t node i j\ t identG ident t node i j\ t symbol t [� elems i k res tokens k symbol
tokens k ]
� � tokens k parse_expression res elems res elems res k tokens k symbol tokens k ,� k k� � m � list elems node k j\ t symbol t {7 pairs i k val_res string key_node tokens k symbol
tokens k }
. - tokens k string� string tokens k key_node k k tokens k ident� string tokens k key_node k k tokens k parse_expression val_res val_res key_node val_res k k k tokens k parse_expression val_res pairs key_node val_res pairs val_res k tokens k symbol tokens k ,+ k k, - � . dict pairs node k j\ t symbol t (T tokens i parse_expression res res node res j\ number node i j inner end_res call_args res attr j tok_len tokens j symbolM
tokens j (� j k call_args tokens k symbol
tokens k )
� � tokens k parse_expression res call_args res call_args res k tokens k symbol tokens k ,� k k� � � � func_call node call_args node k jL
tokens j [1
tokens j parse_expression inner inner k tokens k symbol tokens k :%
tokens k symbol tokens k ]
slice node inner node k j$
tokens k parse_expression end_res slice node inner end_res node end_res j0
index node inner node k jL
tokens j .K
tokens j attr dot node attr node j jL
M
n node j $$ i entry env! length env_len i env_lens
env i entry entry namen
entry $n
i iY
i entry
global_env! length
global_len i
global_len�
global_env i entry entry name�
entry $�
i iz
$$ i entry env! length env_len i env_len�
env i entry entry name�
env i name value ' env$�
i i�
env name value env env$$ result i entry env! length env_len i env_len�
env i entry result entry result i i�
result$$ res i path! length n i n path i \�
res / res res path i res i i�
res$$ path normalize_path path path! length i i ! path i / ! i i i + path i$+ .$$ base normalize_path base rel normalize_path rel path rel! length rel /D rel pathJ base / rel path parts part i path! length n abs n path /b absb i n� path i /� part ..� parts! length parts parts! length ..
� parts parts! length parts� parts .. parts� part
part .
� parts part parts� part� part path i part i ib part ..� parts! length parts parts! length ..
� parts parts! length parts� parts .. parts� part
part .
� parts part parts� res i parts! length p_len i p_len� res
� res / res� res parts i res i i� abs� / res res� res
abs /$ .$
res$$ i source! length src_len i src_len source i source i source i
source i
3 i i i src_len� source i ; source i ; source i ; source i o source i m source i g� i i i src_len source i
z i iz i src_len source i
� i i� source i#$� � /