-
Notifications
You must be signed in to change notification settings - Fork 1
/
ast.a68
93 lines (74 loc) · 3.24 KB
/
ast.a68
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
91
92
COMMENT
Prog = Decl+
Decl = VarDecl | FunDecl
Vardecl = Mode id '=' Expr ';'
FunDecl = RetType id '(' [Fargs] ')' '{' VarDecl* Stmt+ '}'
Moid = Mode | 'Void'
Mode = 'Int' | 'Bool' | '(' Mode ',' Mode ')' | '[' Mode ']' | id
FArgs = Mode id [ ',' FArgs ]
Stmt = '{' Stmt* '}'
| 'if' '(' Expr ')' Stmt [ 'else' Stmt ]
| 'while' '(' Expr ')' Stmt
| id '=' Expr
| FunCall ';'
| 'return' Expr ';'
Expr = Primary [ DyOp Expr ]
Primary = id
| MonOp Primary
| integral | 'False' | 'True' | '[]'
| '(' Expr ')'
| FunCall
| '[]'
| '(' Expr ',' Expr ')'
FunCall = id '(' [ActArgs ] ')'
ActArgs = Expr [ ',' ActArgs ]
MonOp = '!' | '-'
DyOp = + - * / % == < > <= >= != && || :
integral = digit+
id = alpha ('_' | alphaNum)*
COMMENT
MODE SYMBOL = STRUCT(STRING repr, [2]INT pos);
MODE CONST = STRUCT(INT int, [2]INT pos);
MODE IDENT = STRUCT(STRING name, [2]INT pos, REF DECLINFO info);
MODE MONAD = STRUCT(SYMBOL op, REF EXPR lhs);
MODE DYAD = STRUCT(SYMBOL op, REF EXPR lhs, rhs);
MODE TUPLE = STRUCT(REF EXPR lhs, rhs, [2]INT pos);
MODE FUNCALL = STRUCT(IDENT id, REF[]EXPR args);
MODE EXPR = UNION(SYMBOL,CONST,MONAD,DYAD,TUPLE,IDENT,FUNCALL);
# auto-extensions; prev: TYPE type #
MODE DECLSTM = STRUCT(REF TYPE type, IDENT id, EXPR value);
MODE IFSTM = STRUCT(EXPR cond, REF STM then, else);
MODE WHILESTM= STRUCT(EXPR cond, REF STM body);
MODE ASSIGN = STRUCT(IDENT id, EXPR value);
MODE RETURN = STRUCT(UNION(EXPR,VOID) value, [2]INT pos);
MODE STM = UNION(REF STMLIST,IFSTM,WHILESTM,ASSIGN,DECLSTM,FUNCALL,RETURN);
MODE STMLIST = STRUCT(STM stm, REF STMLIST tail);
# since we modify these after parsing, ret is a REF #
MODE DECLFUN = STRUCT(PARAMS args, REF STMLIST body, REF INT frame size, REF FLEX[]PARAM unifiers);
MODE PARAMS = REF[] PARAM;
MODE PARAM = STRUCT(REF TYPE type, IDENT id);
MODE DECL = UNION(DECLFUN,DECLSTM);
MODE DECLS = STRUCT(DECL decl, REF DECLS tail);
CO we don't actually use FUNT, although it is already here in case we want unify DECLFUN and DECLSTM,
in which case it will be handy. only astprint/astdump support it at present CO
MODE LISTT = STRUCT(REF TYPE lt, INT dummy);
MODE PAIRT = STRUCT(REF TYPE lt, rt);
MODE FUNT = STRUCT(REF[]TYPE args, REF TYPE ret);
MODE TYPE = UNION(SYMBOL,LISTT,PAIRT,IDENT,FUNT,UNIFIER,TYPELNK);
MODE DECLINFO= STRUCT(UNION(DECL,PARAM) decl, INT pos);
MODE UNIFIER = INT; # only used as a placeholder type #
MODE TYPELNK = STRUCT(REF TYPE alias,BOOL dummy);
# auto-extension #
[]STRING reserved words =
("Void", "Int", "Bool", "Auto", "True", "False","if","while","else","return");
PROC function id = (DECLFUN decl)IDENT: id OF (args OF decl)[0];
PROC ret type = (DECLFUN decl)TYPE: type OF (args OF decl)[0];
OP = = (SYMBOL t, STRING s)BOOL: s = repr OF t;
OP = = (SYMBOL t, CHAR s)BOOL: s = repr OF t;
# two routines easing iteration #
PROC for each decl = (REF DECLS list, PROC (REF DECL)VOID p)VOID:
(REF DECLS cur := list;
WHILE REF DECLS(cur) ISNT NIL DO p(decl OF cur); cur := tail OF cur OD);
PROC for each stm = (REF STMLIST list, PROC (REF STM)VOID p)VOID:
(REF STMLIST cur := list;
WHILE REF STMLIST(cur) ISNT NIL DO p(stm OF cur); cur := tail OF cur OD);