summaryrefslogtreecommitdiff
path: root/src/parser.mly
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.mly')
-rw-r--r--src/parser.mly137
1 files changed, 113 insertions, 24 deletions
diff --git a/src/parser.mly b/src/parser.mly
index 194a899..307a679 100644
--- a/src/parser.mly
+++ b/src/parser.mly
@@ -13,10 +13,17 @@
| VId of ident
| VPtr of var
| VRef of var
+
+ (* return type, name *)
let rec reverse_var bt v = match v with
- | VId(i) -> i, bt
- | VPtr(vv) -> let id, ty = reverse_var bt vv in id, TPtr(ty)
- | VRef(vv) -> let id, ty = reverse_var bt vv in id, TRef(ty)
+ | VId(i) -> bt, i
+ | VPtr(vv) -> let ty, id = reverse_var bt vv in TPtr(ty), id
+ | VRef(vv) -> let ty, id = reverse_var bt vv in TRef(ty), id
+
+ (* return type, class, name *)
+ let rec reverse_qvar bt (v, cl) =
+ let ty, na = reverse_var bt v in
+ ty, cl, na
%}
%token <int> INTVAL
@@ -48,7 +55,7 @@
%left LT LE GT GE
%left PLUS MINUS
%left TIMES DIV MOD
-%left RARROW DOT LPAREN
+%nonassoc LPAREN
%start <Ast.program> prog
@@ -62,13 +69,71 @@ prog:
;
declaration:
-| ident = typed_var
- LPAREN args = typed_var* RPAREN
+| p = proto
b = block
- { [ DFunction({p_ret_type = snd ident; p_name = fst ident; p_args = args}, b) ] }
+ { [ DFunction(p, b) ] }
| vars = typed_vars
SEMICOLON
{ List.map (fun k -> DGlobal(k)) vars }
+| n = cls
+ s = supers? LBRACE PUBLIC COLON
+ m = member* RBRACE SEMICOLON
+ {
+ [ DClass({
+ c_name = n;
+ c_supers = s;
+ c_members = List.flatten m;
+ }) ]
+ }
+;
+
+cls:
+ CLASS n = IDENT
+ {
+ type_names := Sset.add n !type_names;
+ n
+ }
+;
+
+supers:
+ COLON s = separated_nonempty_list(COMMA, preceded(PUBLIC, TIDENT)) { s }
+;
+
+member:
+| k = typed_vars SEMICOLON
+ { List.map (fun (x, y) -> CVar(x, y)) k }
+| p = cls_proto SEMICOLON
+ { [ CMethod(p) ] }
+| VIRTUAL p = cls_proto SEMICOLON
+ { [ CVirtualMethod(p) ] }
+;
+
+cls_proto:
+| ident = typed_var
+ LPAREN args = separated_list(COMMA, typed_var) RPAREN
+ { {p_ret_type = Some(fst ident); p_name = snd ident; p_class = None; p_args = args} }
+| cls = TIDENT
+ LPAREN args = separated_list(COMMA, typed_var) RPAREN
+ { {p_ret_type = None; p_name = cls; p_class = Some cls; p_args = args} }
+;
+
+proto:
+| ident = typed_qvar
+ LPAREN args = separated_list(COMMA, typed_var) RPAREN
+ {
+ let ty, cl, na = ident in
+ { p_ret_type = Some ty; p_name = na; p_class = cl; p_args = args} }
+| cls = TIDENT DOUBLECOLON cls2 = TIDENT
+ LPAREN args = separated_list(COMMA, typed_var) RPAREN
+ {
+ {p_ret_type = None; p_name = cls2; p_class = Some cls; p_args = args}
+ }
+;
+
+base_type:
+| VOID { TVoid }
+| INT { TInt }
+| t = TIDENT { TIdent(t) }
;
typed_var:
@@ -83,18 +148,25 @@ typed_vars:
{ List.map (reverse_var b) x }
;
-base_type:
-| VOID { TVoid }
-| INT { TInt }
-| t = TIDENT { TIdent(t) }
-;
-
var:
| t = IDENT { VId(t) }
| TIMES v = var { VPtr(v) }
| REF v = var { VRef(v) }
;
+typed_qvar:
+| b = base_type
+ x = qvar
+ { reverse_qvar b x }
+;
+
+qvar:
+| c = TIDENT DOUBLECOLON t = IDENT { VId(t), Some(c) }
+| t = IDENT { VId(t), None }
+| TIMES v = qvar { VPtr(fst v), snd v }
+| REF v = qvar { VRef(fst v), snd v }
+;
+
block:
| LBRACE
i = statement*
@@ -136,8 +208,16 @@ common_statement:
{ SBlock (b) }
| RETURN e = expression? SEMICOLON
{ SReturn (e) }
-| k = typed_var v = preceded(ASSIGN, expression)? SEMICOLON
- { SDeclare(fst k, snd k, v) }
+| k = typed_var SEMICOLON
+ { SDeclare(fst k, snd k) }
+| k = typed_var ASSIGN v = expression SEMICOLON
+ { SDeclareAssignExpr(fst k, snd k, v) }
+| k = typed_var ASSIGN cls = TIDENT LPAREN args = separated_list(COMMA, expression) RPAREN SEMICOLON
+ { SDeclareAssignConstructor(fst k, snd k, cls, args) }
+| STD_COUT
+ a = nonempty_list(preceded(LFLOW, str_expression))
+ SEMICOLON
+ { SWriteCout(a) }
;
expression:
@@ -145,15 +225,7 @@ expression:
| a = expression b = binop c = expression { EBinary(a, b, c) }
| a = expression LPAREN arg = separated_list(COMMA, expression) RPAREN { ECall(a, arg) }
| a = unop { a }
-;
-
-primary:
-| NULL { ENull }
-| i = INTVAL { EInt(i) }
-| TRUE { EBool(true) }
-| FALSE { EBool(false) }
-| i = IDENT { EIdent(i) }
-| LPAREN e = expression RPAREN { e }
+| NEW c = TIDENT LPAREN args = separated_list(COMMA, expression) RPAREN { ENew(c, args) }
;
%inline binop:
@@ -172,6 +244,18 @@ primary:
| MOD { Modulo }
;
+primary:
+| NULL { ENull }
+| THIS { EThis }
+| i = INTVAL { EInt(i) }
+| TRUE { EBool(true) }
+| FALSE { EBool(false) }
+| i = IDENT { EIdent(i) }
+| LPAREN e = expression RPAREN { e }
+| a = primary RARROW b = IDENT { EMember(EUnary(Deref, a), b) }
+| a = primary DOT b = IDENT { EMember(a, b) }
+;
+
unop:
| e = lunop { e }
| e = unop INCR { EUnary(PostIncr, e) }
@@ -188,3 +272,8 @@ lunop:
| DECR e = lunop { EUnary(PreDecr, e) }
| e = primary { e }
;
+
+str_expression:
+| e = expression { SEExpr(e) }
+| s = STRVAL { SEStr(s) }
+;