diff options
| author | Alasdair Armstrong | 2018-01-03 18:50:21 +0000 |
|---|---|---|
| committer | Alasdair Armstrong | 2018-01-03 18:50:21 +0000 |
| commit | 05c2d0f45dcc632a11b4868b04776c1916b41454 (patch) | |
| tree | e61ff83f943a58231c4ebd82d030c2f21a8f5763 /src/lexer2.mll | |
| parent | 90ca4e03c240675b1830a5e48cea5f6c9e412b2a (diff) | |
Lots of experimental changes on this branch
* Changed comment syntax to C-style /* */ and //
* References to registers and mutable variables are never created
implicitly - a reference to a register or variable R is now created
via the expression "ref R". References are assigned like "(*Y) = X",
with "(*ref R) = X" being equivalent to "R = X". Everything is always
explicit now, which simplifies the logic in the typechecker. There's
also now an invariant that every id directly in a LEXP is mutable,
which is actually required for our rewriter steps to be sound.
* More flexible syntax for L-expressions to better support wierd
power-idioms, some syntax sugar means that:
X.GET(a, b, c) ==> _mod_GET(X, a, b, c)
X->GET(a, b, c) ==> _mod_GET(ref X, a, b, c)
for setters, this can be combined with the (still somewhat poorly
named) LEXP_memory construct, such that:
X->SET(a, b, c) = Y ==> _mod_SET(ref X, a, b, c, Y)
Currently I use the _mod_ prefix for these 'modifier' functions, but
we could omit that a la rust.
* The register bits typedef construct no longer exists in the
typechecker. This construct never worked consistently between backends
and inc/dec vectors, and it can be easily replaced by structs with
fancy setters/getters if need be. One can also use custom type operators to mimic the syntax, i.e.
type operator ... ('n : Int) ('m : Int) = slice('n, 'm)
struct cr = {
CR0 : 32 ... 35,
/* 32 : LT; 33 : GT; 34 : EQ; 35 : SO; */
CR1 : 36 ... 39,
/* 36 : FX; 37 : FEX; 38 : VX; 39 : OX; */
CR2 : 40 ... 43,
CR3 : 44 ... 47,
CR4 : 48 ... 51,
CR5 : 52 ... 55,
CR6 : 56 ... 59,
CR7 : 60 ... 63,
}
This greatly simplifies a lot of the logic in the typechecker, as it
means that E_field is no longer ambiguously overloaded between records
and register bit typedefs. This also makes writing semantics for these
constructs much simpler.
Diffstat (limited to 'src/lexer2.mll')
| -rw-r--r-- | src/lexer2.mll | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/lexer2.mll b/src/lexer2.mll index b293046f..312183fa 100644 --- a/src/lexer2.mll +++ b/src/lexer2.mll @@ -231,6 +231,8 @@ rule token = parse | "->" { MinusGt } | "=>" { EqGt(r "=>") } | "<=" { (LtEq(r"<=")) } + | "/*" { comment (Lexing.lexeme_start_p lexbuf) 0 lexbuf; token lexbuf } + | "*/" { raise (LexError("Unbalanced comment", Lexing.lexeme_start_p lexbuf)) } | "infix" ws (digit as p) ws (operator as op) { operators := M.add op (mk_operator Infix (int_of_string (Char.escaped p)) op) !operators; Fixity (Infix, Big_int.of_string (Char.escaped p), op) } @@ -243,8 +245,6 @@ rule token = parse | operator as op { try M.find op !operators with Not_found -> raise (LexError ("Operator fixity undeclared " ^ op, Lexing.lexeme_start_p lexbuf)) } - | "(*" { comment (Lexing.lexeme_start_p lexbuf) 0 lexbuf; token lexbuf } - | "*)" { raise (LexError("Unbalanced comment", Lexing.lexeme_start_p lexbuf)) } | tyvar_start startident ident* as i { TyVar(r i) } | "~" { Id(r"~") } | startident ident* as i { if M.mem i kw_table then @@ -269,8 +269,8 @@ rule token = parse and comment pos depth = parse - | "(*" { comment pos (depth+1) lexbuf } - | "*)" { if depth = 0 then () + | "/*" { comment pos (depth+1) lexbuf } + | "*/" { if depth = 0 then () else if depth > 0 then comment pos (depth-1) lexbuf else assert false } | "\n" { Lexing.new_line lexbuf; |
