%token WHILE
/* from lowest precedence */
+%left THEN
+%left ELSE
+%nonassoc ASSIGN
+%left OF DO
%left OR
%left AND
%nonassoc EQ NEQ GT LT GE LE
{
sprintf "program[%s]" $1
}
+ ;
exp:
| NIL
| ID LBRACK exp RBRACK OF exp
{
let type_id = $1 in
- let exp_1 = $3 in
- let exp_2 = $6 in
- sprintf "array[type[%s], size[%s], val[%s]]" type_id exp_1 exp_2
+ let number_of_elements = $3 in
+ let initial_value = $6 in
+ sprintf
+ "array[type[%s], size[%s], val[%s]]"
+ type_id number_of_elements initial_value
}
| ID LBRACE rec_field_assignments RBRACE
{
let fun_args = $3 in
sprintf "fun_call[%s, %s]" id fun_args
}
- | exp op exp
+ | exp PLUS exp
+ {
+ sprintf "op_plus[%s + %s]" $1 $3
+ }
+ | exp MINUS exp
+ {
+ sprintf "op_minus[%s - %s]" $1 $3
+ }
+ | exp TIMES exp
+ {
+ sprintf "op_times[%s * %s]" $1 $3
+ }
+ | exp DIVIDE exp
+ {
+ sprintf "op_divide[%s / %s]" $1 $3
+ }
+ | exp EQ exp
+ {
+ sprintf "op_eq[%s = %s]" $1 $3
+ }
+ | exp NEQ exp
+ {
+ sprintf "op_neq[%s <> %s]" $1 $3
+ }
+ | exp GT exp
+ {
+ sprintf "op_gt[%s > %s]" $1 $3
+ }
+ | exp LT exp
+ {
+ sprintf "op_lt[%s < %s]" $1 $3
+ }
+ | exp GE exp
+ {
+ sprintf "op_ge[%s >= %s]" $1 $3
+ }
+ | exp LE exp
+ {
+ sprintf "op_le[%s <= %s]" $1 $3
+ }
+ | exp AND exp
{
- sprintf "op[%s %s %s]" $1 $2 $3
+ sprintf "op_and[%s & %s]" $1 $3
+ }
+ | exp OR exp
+ {
+ sprintf "op_or[%s | %s]" $1 $3
}
| IF exp THEN exp ELSE exp
{
(* Perhaps "void"? *)
"unit[]"
}
+ ;
+
+rec_field_assignments:
+ | ID EQ exp
+ {
+ let id = $1 in
+ let exp = $3 in
+ sprintf "%S = %s" id exp
+ }
+ | ID EQ exp COMMA rec_field_assignments
+ {
+ let id = $1 in
+ let exp = $3 in
+ let rec_field_assignments = $5 in
+ sprintf "%S = %s, %s" id exp rec_field_assignments
+ }
+ ;
exps:
| exp
{
- sprintf "%s" $1
+ let exp = $1 in
+ sprintf "%s" exp
}
| exp SEMICOLON exps
{
- sprintf "%s; %s" $1 $3
+ let exp = $1 in
+ let exps = $3 in
+ sprintf "%s; %s" exp exps
}
+ ;
decs:
| dec
{
sprintf "%s %s" $1 $2
}
+ ;
dec:
- | tydec {$1}
- | vardec {$1}
- | fundec {$1}
-
-fundec:
- | FUNCTION ID LPAREN RPAREN EQ exp
+ /* Tydec */
+ | TYPE ID EQ ID
{
- let id = $2 in
- let exp = $6 in
- sprintf "fundec[%s, arguments[], exp[%s]]" id exp
+ let type_id_new = $2 in
+ let type_id_orig = $4 in
+ sprintf "tydec_alias[from[%s], to[%s]]" type_id_new type_id_orig
}
- | FUNCTION ID LPAREN tyfields RPAREN EQ exp
+ | TYPE ID EQ LBRACE RBRACE
{
- let id = $2 in
- let tyfields = $4 in
- let exp = $7 in
- sprintf "fundec[%s, arguments[%s], exp[%s]]" id tyfields exp
+ let type_id = $2 in
+ sprintf "tydec_empty_record[%s]" type_id
}
- | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
+ | TYPE ID EQ LBRACE tyfields RBRACE
{
- let id = $2 in
- let tyfields = $4 in
- let type_id = $7 in
- let exp = $9 in
- sprintf
- "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
- id tyfields type_id exp
+ let type_id = $2 in
+ let tyfields = $5 in
+ sprintf "tydec_record[%s, fields[%s]]" type_id tyfields
+ }
+ | TYPE ID EQ ARRAY OF ID
+ {
+ let type_id = $2 in
+ let element_type_id = $6 in
+ sprintf "tydec_array[%s, elements_of_type[%s]]" type_id element_type_id
}
-vardec:
+ /* Vardec */
| VAR ID ASSIGN exp
{
let id = $2 in
sprintf "vardec[%s, type_id[%s], exp[%s]]" id type_id exp
}
-tydec:
- | TYPE ID EQ ty
- {
- let type_id = $2 in
- let ty = $4 in
- sprintf "tydec[%s, %s]" type_id ty
- }
-
-ty:
- | ID
- {
- let type_id = $1 in
- sprintf "type[type_id[%S]]" type_id
- }
- | LBRACE RBRACE
+ /* Fundec */
+ | FUNCTION ID LPAREN RPAREN EQ exp
{
- "record[]"
+ let id = $2 in
+ let exp = $6 in
+ sprintf "fundec[%s, arguments[], exp[%s]]" id exp
}
- | LBRACE tyfields RBRACE
+ | FUNCTION ID LPAREN tyfields RPAREN EQ exp
{
- let tyfields = $2 in
- sprintf "record[%s]" tyfields
+ let id = $2 in
+ let tyfields = $4 in
+ let exp = $7 in
+ sprintf "fundec[%s, arguments[%s], exp[%s]]" id tyfields exp
}
- | ARRAY OF ID
+ | FUNCTION ID LPAREN tyfields RPAREN COLON ID EQ exp
{
- let type_id = $3 in
- sprintf "array_of_type[%s]" type_id
+ let id = $2 in
+ let tyfields = $4 in
+ let type_id = $7 in
+ let exp = $9 in
+ sprintf
+ "fundec[%s, tyfields[%s], type_id[%s], exp[%s]]"
+ id tyfields type_id exp
}
+ ;
tyfields:
-/*| epsilon */
- | tyfield
- {$1}
- | tyfield COMMA tyfields
- {
- let tyfield = $1 in
- let tyfields = $3 in
- sprintf "%s, %s" tyfield tyfields
- }
-
-tyfield:
| ID COLON ID
{
- let id = $1 in
- let type_id = $3 in
- sprintf "tyfield[%s, %s]" id type_id
+ let id_1 = $1 in
+ let id_2 = $3 in
+ sprintf "%s : %s" id_1 id_2
}
-
-rec_field_assignments:
- | ID EQ exp
+ | ID COLON ID COMMA tyfields
{
- let id = $1 in
- let exp = $3 in
- sprintf "%S = %s" id exp
- }
- | ID EQ exp COMMA rec_field_assignments
- {
- let id = $1 in
- let exp = $3 in
- let rec_field_assignments = $5 in
- sprintf "%S = %s, %s" id exp rec_field_assignments
+ let id_1 = $1 in
+ let id_2 = $3 in
+ let tyfield = sprintf "%s : %s" id_1 id_2 in
+ let tyfields = $5 in
+ sprintf "%s, %s" tyfield tyfields
}
+ ;
fun_args:
| exp
{
sprintf "%s, %s" $1 $3
}
-
-op:
- | PLUS {"+"}
- | MINUS {"-"}
- | TIMES {"*"}
- | DIVIDE {"/"}
- | EQ {"="}
- | NEQ {"<>"}
- | GT {">"}
- | LT {"<"}
- | GE {">="}
- | LE {"<="}
- | AND {"&"}
- | OR {"|"}
+ ;
lvalue:
- | ID
+ | ID lvalue_part
{
let id = $1 in
- sprintf "lvalue[%s]" id
+ let part = $2 in
+ sprintf "lvalue[%s, part[%s]]" id part
}
- | lvalue DOT ID
+ ;
+
+lvalue_part:
+ | {"epsilon[]"}
+ | lvalue_subscript {$1}
+ | lvalue_field_access {$1}
+ ;
+
+lvalue_subscript:
+ | LBRACK exp RBRACK
{
- let record = $1 in
- let field = $3 in
- sprintf "get_record_field[%s, %s]" record field
+ let exp = $2 in
+ sprintf "subscript[%s]" exp
}
- | lvalue LBRACK exp RBRACK
+ ;
+
+lvalue_field_access:
+ | DOT ID
{
- let array = $1 in
- let subscript = $3 in
- sprintf "get_array_subscript[%s, %s]" array subscript
+ let field = $2 in
+ sprintf "field_access[%s]" field
}
+ ;
%%