summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2013-11-25 15:06:21 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2013-11-25 15:06:21 +0100
commitf9ac80d948ecedcf9e04b94b5b529a31f23589a9 (patch)
treeac566d8756c19367a7eecc39363bd979c61bf8c5
parent415f94f0978fbf3104f93033fe21ec88f2ec454f (diff)
downloadLPC-Projet-f9ac80d948ecedcf9e04b94b5b529a31f23589a9.tar.gz
LPC-Projet-f9ac80d948ecedcf9e04b94b5b529a31f23589a9.zip
Added localisation for expressions and statements.
-rw-r--r--src/ast.ml30
-rw-r--r--src/parser.mly61
-rw-r--r--src/pretty.ml9
3 files changed, 74 insertions, 26 deletions
diff --git a/src/ast.ml b/src/ast.ml
index f815c83..d23b573 100644
--- a/src/ast.ml
+++ b/src/ast.ml
@@ -12,6 +12,8 @@ let type_names = ref Sset.empty
type ident = string
type tident = string
+type loc = Lexing.position * Lexing.position
+
type binop =
| Equal | NotEqual
| Lt | Le | Gt | Ge
@@ -31,7 +33,10 @@ type var_type =
| TRef of var_type
| TIdent of tident
-type expression =
+type expression = {
+ e_loc: loc;
+ e_desc: expr_desc }
+and expr_desc =
| EInt of int
| EBool of bool
| ENull
@@ -42,13 +47,19 @@ type expression =
| EUnary of unop * expression
| EBinary of expression * binop * expression
| EMember of expression * ident
- | ENew of ident * expression list
+ | ENew of tident * expression list
-type str_expression =
- | SEExpr of expression
+type str_expression = {
+ se_loc: loc;
+ se_desc : se_desc }
+and se_desc =
+ | SEExpr of expr_desc
| SEStr of string
-type statement =
+type statement = {
+ s_loc: loc;
+ s_desc: s_desc }
+and s_desc =
| SEmpty
| SExpr of expression
| SIf of expression * statement * statement
@@ -58,14 +69,15 @@ type statement =
| SReturn of expression option
| SDeclare of var_type * ident
| SDeclareAssignExpr of var_type * ident * expression
- | SDeclareAssignConstructor of var_type * ident * ident * expression list
+ | SDeclareAssignConstructor of var_type * ident * tident * expression list
(* Type of variable, variable name, constructor class name, constructor arguments *)
| SWriteCout of str_expression list
and block = statement list
type proto = {
+ p_loc : loc;
p_name : ident;
- p_class : ident option; (* p_class = none : standalone function *)
+ p_class : tident option; (* p_class = none : standalone function *)
p_ret_type : var_type option; (* p_class = some and p_ret_type = none : constructor *)
p_args : (var_type * ident) list;
}
@@ -76,8 +88,8 @@ type cls_mem =
| CVirtualMethod of proto
type cls = {
- c_name : ident;
- c_supers : ident list option;
+ c_name : tident;
+ c_supers : tident list option;
c_members : cls_mem list;
}
diff --git a/src/parser.mly b/src/parser.mly
index eb0a959..39fdf7d 100644
--- a/src/parser.mly
+++ b/src/parser.mly
@@ -111,10 +111,19 @@ member:
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} }
+ { {
+ p_ret_type = Some(fst ident);
+ p_name = snd ident;
+ p_class = None;
+ p_args = args;
+ p_loc = $startpos, $endpos } }
| cls = TIDENT
LPAREN args = separated_list(COMMA, typed_var) RPAREN
- { {p_ret_type = None; p_name = cls; p_class = Some cls; p_args = args} }
+ { {p_ret_type = None;
+ p_name = cls;
+ p_class = Some cls;
+ p_args = args;
+ p_loc = $startpos, $endpos } }
;
proto:
@@ -122,11 +131,11 @@ proto:
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} }
+ { p_ret_type = Some ty; p_name = na; p_class = cl; p_args = args; p_loc = $startpos, $endpos } }
| 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}
+ {p_ret_type = None; p_name = cls2; p_class = Some cls; p_args = args; p_loc = $startpos, $endpos}
}
;
@@ -175,9 +184,12 @@ block:
;
statement:
+| d = statement_desc { { s_loc = $startpos, $endpos; s_desc = d } }
+;
+statement_desc:
| k = common_statement { k }
| IF LPAREN c = expression RPAREN s = statement
- { SIf(c, s, SEmpty) }
+ { SIf(c, s, { s_loc = $startpos, $endpos; s_desc = SEmpty}) }
| IF LPAREN c = expression RPAREN s = no_if_statement ELSE t = statement
{ SIf(c, s, t) }
| WHILE LPAREN c = expression RPAREN s = statement
@@ -190,6 +202,9 @@ statement:
;
no_if_statement:
+| d = no_if_statement_desc { { s_loc = $startpos, $endpos; s_desc = d } }
+;
+no_if_statement_desc:
| WHILE LPAREN c = expression RPAREN s = no_if_statement
{ SWhile(c, s) }
| FOR LPAREN k = separated_list(COMMA, expression) SEMICOLON
@@ -221,10 +236,14 @@ common_statement:
;
expression:
+| e = expression_desc
+ { { e_loc = $startpos, $endpos; e_desc = e } }
+| l = lunop { l }
+;
+expression_desc:
| e1 = expression ASSIGN e2 = expression { EAssign(e1, e2) }
| a = expression b = binop c = expression { EBinary(a, b, c) }
| a = expression LPAREN arg = separated_list(COMMA, expression) RPAREN { ECall(a, arg) }
-| a = lunop { a }
| NEW c = TIDENT LPAREN args = separated_list(COMMA, expression) RPAREN { ENew(c, args) }
;
@@ -245,24 +264,41 @@ expression:
;
primary:
+| LPAREN e = expression RPAREN
+ { { e_loc = $startpos, $endpos; e_desc = e.e_desc } }
+| k = primary_desc
+ { { e_loc = $startpos, $endpos; e_desc = k } }
+;
+primary_desc:
| 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) }
+| a = primary RARROW b = IDENT
+ { EMember(
+ { e_loc = $startpos, $endpos; e_desc = EUnary(Deref, a)}
+ , b) }
+| a = primary DOT b = IDENT
+ { EMember(a, b) }
;
runop:
-| e = primary { e }
+| e = runop_desc { { e_loc = $startpos, $endpos; e_desc = e } }
+| p = primary { p }
+;
+runop_desc:
| e = runop INCR { EUnary(PostIncr, e) }
| e = runop DECR { EUnary(PostDecr, e) }
;
lunop:
+| e = lunop_desc
+ { { e_loc = $startpos, $endpos; e_desc = e } }
+| k = runop { k }
+;
+lunop_desc:
| NOT e = lunop { EUnary(Not, e) }
| MINUS e = lunop { EUnary(Minus, e) }
| PLUS e = lunop { EUnary(Plus, e) }
@@ -270,10 +306,9 @@ lunop:
| TIMES e = lunop { EUnary(Deref, e) }
| INCR e = lunop { EUnary(PreIncr, e) }
| DECR e = lunop { EUnary(PreDecr, e) }
-| e = runop { e }
;
str_expression:
-| e = expression { SEExpr(e) }
-| s = STRVAL { SEStr(s) }
+| e = expression { { se_loc = e.e_loc; se_desc = SEExpr(e.e_desc) } }
+| s = STRVAL { { se_loc = $startpos, $endpos; se_desc = SEStr(s) } }
;
diff --git a/src/pretty.ml b/src/pretty.ml
index 1307bdf..e618bfa 100644
--- a/src/pretty.ml
+++ b/src/pretty.ml
@@ -84,7 +84,7 @@ let rec var_type_str = function
| TVoid -> "void" | TInt -> "int" | TIdent(i) -> i
| TPtr(k) -> "*" ^ (var_type_str k)
| TRef(k) -> "&" ^ (var_type_str k)
-let rec expr_string = function
+let rec expr_string e = match e.e_desc with
| EInt(i) -> string_of_int i
| EBool(b) -> (if b then "true" else "false")
| ENull -> "NULL"
@@ -99,7 +99,7 @@ let rec expr_string = function
let rec print_stmt l x =
for i = 1 to l do print_string " " done;
- match x with
+ match x.s_desc with
| SEmpty -> print_string ";\n"
| SExpr(e) -> print_string ((expr_string e) ^ "\n")
| SIf(e, a, b) -> print_string ("if " ^ (expr_string e) ^ "\n");
@@ -124,8 +124,9 @@ let rec print_stmt l x =
(i ^ " : " ^ (var_type_str t) ^ " = " ^ c ^ "(" ^
(csl expr_string a) ^ ")\n")
| SWriteCout(k) -> print_string ("std::cout" ^
- (List.fold_left (fun x k -> x ^ " << " ^ (match k with
- | SEExpr(k) -> expr_string k | SEStr("\n") -> "std::endl" | SEStr(s) -> "`" ^ s ^ "`")) "" k) ^ "\n")
+ (List.fold_left (fun x k -> x ^ " << " ^ (match k.se_desc with
+ | SEExpr(e) -> expr_string {e_loc = k.se_loc; e_desc = e}
+ | SEStr("\n") -> "std::endl" | SEStr(s) -> "`" ^ s ^ "`")) "" k) ^ "\n")
and print_block n b =
let prefix = String.make n ' ' in
print_string (prefix ^ "{\n");