commit a251d8176239e4c45b9cb39bb83fde28770f37df
parent 851cc1e1b24f6ff7666bf298ecfb0948d6383cad
Author: Eyal Sawady <ecs@d2evs.net>
Date: Fri, 28 May 2021 11:45:11 -0400
ast::_type: track end location
Also fix issues with start location tracking.
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
7 files changed, 65 insertions(+), 37 deletions(-)
diff --git a/hare/ast/type.ha b/hare/ast/type.ha
@@ -115,7 +115,8 @@ export type type_flags = enum uint {
// A Hare type.
export type _type = struct {
- loc: lex::location,
+ start: lex::location,
+ end: lex::location,
flags: type_flags,
_type: (alias_type | builtin_type | enum_type | func_type |
list_type | pointer_type | struct_type | union_type |
diff --git a/hare/parse/decl.ha b/hare/parse/decl.ha
@@ -125,8 +125,9 @@ fn decl_func(lexer: *lex::lexer) (ast::decl_func | error) = {
want(lexer, ltok::FN)?;
let ident_loc = lex::mkloc(lexer);
let ident = ident(lexer)?;
- let proto_loc = lex::mkloc(lexer);
+ let proto_start = lex::mkloc(lexer);
let prototype = prototype(lexer)?;
+ let proto_end = lex::prevloc(lexer);
if (noreturn) {
prototype.attrs |= ast::func_attrs::NORETURN;
};
@@ -151,7 +152,8 @@ fn decl_func(lexer: *lex::lexer) (ast::decl_func | error) = {
symbol = sym,
ident = ident,
prototype = ast::_type {
- loc = proto_loc,
+ start = proto_start,
+ end = proto_end,
flags = ast::type_flags::CONST,
_type = prototype,
},
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -964,7 +964,8 @@ fn match_case(lexer: *lex::lexer) (ast::match_case | error) = {
ltok::NULL => {
want(lexer, ltok::NULL)?;
("", ast::_type {
- loc = loc,
+ start = loc,
+ end = lex::prevloc(lexer),
flags = 0,
_type = ast::builtin_type::NULL,
});
@@ -997,7 +998,8 @@ fn match_expr(lexer: *lex::lexer) (ast::expr | error) = {
void => {
let case = match_case(lexer)?;
case._type = alloc(ast::_type {
- loc = case._type.loc,
+ start = t.2,
+ end = case._type.end,
flags = 0,
_type = ast::pointer_type {
referent = case._type,
diff --git a/hare/parse/parse.ha b/hare/parse/parse.ha
@@ -90,7 +90,7 @@ fn synassert(loc: lex::location, cond: bool, msg: str) (void | error) = {
fn nametype(lexer: *lex::lexer) ((str, ast::_type) | error) = {
let tok = peek(lexer)? as lex::token;
- let loc = tok.2;
+ const start = tok.2;
return switch (tok.0) {
ltok::NAME => {
let name = tok.1 as str;
@@ -106,7 +106,8 @@ fn nametype(lexer: *lex::lexer) ((str, ast::_type) | error) = {
let id = ident(lexer)?;
insert(id[0], name);
("", ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = 0,
_type = ast::alias_type {
unwrap = false,
@@ -115,7 +116,8 @@ fn nametype(lexer: *lex::lexer) ((str, ast::_type) | error) = {
});
},
* => ("", ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = 0,
_type = ast::alias_type {
unwrap = false,
diff --git a/hare/parse/type.ha b/hare/parse/type.ha
@@ -98,47 +98,55 @@ fn primitive_type(lexer: *lex::lexer) (ast::_type | error) = {
lex::tokstr(tok)),
};
return ast::_type {
- loc = lex::mkloc(lexer),
+ start = tok.2,
+ end = lex::prevloc(lexer),
flags = 0,
_type = builtin,
};
};
fn alias_type(lexer: *lex::lexer) (ast::_type | error) = {
- let loc = lex::mkloc(lexer);
+ const start = lex::mkloc(lexer);
let unwrap = match (try(lexer, ltok::ELLIPSIS)?) {
void => false,
* => true,
};
+ let ident = ident(lexer)?;
return ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = 0,
_type = ast::alias_type {
unwrap = unwrap,
- ident = ident(lexer)?,
+ ident = ident,
},
};
};
fn pointer_type(lexer: *lex::lexer) (ast::_type | error) = {
- let loc = lex::mkloc(lexer);
+ const start = lex::mkloc(lexer);
let flags = match (try(lexer, ltok::NULLABLE)?) {
void => 0: ast::pointer_flags,
* => ast::pointer_flags::NULLABLE,
};
want(lexer, ltok::TIMES)?;
+ let _type = _type(lexer)?;
return ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = 0,
_type = ast::pointer_type {
- referent = alloc(_type(lexer)?),
+ referent = alloc(_type),
flags = flags,
},
};
};
-fn tagged_type(lexer: *lex::lexer, first: ast::_type) (ast::_type | error) = {
- let loc = lex::mkloc(lexer);
+fn tagged_type(
+ lexer: *lex::lexer,
+ first: ast::_type,
+ start: lex::location
+) (ast::_type | error) = {
let tagged: ast::tagged_type = [];
append(tagged, alloc(first));
for (try(lexer, ltok::RPAREN)? is void) {
@@ -152,14 +160,18 @@ fn tagged_type(lexer: *lex::lexer, first: ast::_type) (ast::_type | error) = {
};
};
return ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = 0,
_type = tagged,
};
};
-fn tuple_type(lexer: *lex::lexer, first: ast::_type) (ast::_type | error) = {
- let loc = lex::mkloc(lexer);
+fn tuple_type(
+ lexer: *lex::lexer,
+ first: ast::_type,
+ start: lex::location
+) (ast::_type | error) = {
let tuple: ast::tuple_type = [];
append(tuple, alloc(first));
for (try(lexer, ltok::RPAREN)? is void) {
@@ -173,14 +185,15 @@ fn tuple_type(lexer: *lex::lexer, first: ast::_type) (ast::_type | error) = {
};
};
return ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = 0,
_type = tuple,
};
};
fn fn_type(lexer: *lex::lexer) (ast::_type | error) = {
- let loc = lex::mkloc(lexer);
+ const start = lex::mkloc(lexer);
let attrs = match (try(lexer, ltok::ATTR_NORETURN)?) {
void => 0: ast::func_attrs,
* => ast::func_attrs::NORETURN,
@@ -189,7 +202,8 @@ fn fn_type(lexer: *lex::lexer) (ast::_type | error) = {
let proto = prototype(lexer)?;
proto.attrs |= attrs;
return ast::_type {
- loc = loc,
+ start = start,
+ end = lex::prevloc(lexer),
flags = ast::type_flags::CONST,
_type = proto,
};
@@ -243,13 +257,14 @@ fn struct_union_type(lexer: *lex::lexer) (ast::_type | error) = {
};
return ast::_type {
- loc = kind.2,
+ start = kind.2,
+ end = lex::prevloc(lexer),
+ flags = 0,
_type = switch (kind.0) {
ltok::STRUCT => membs: ast::struct_type,
ltok::UNION => membs: ast::union_type,
* => abort(),
},
- ...
};
};
@@ -314,14 +329,15 @@ fn array_slice_type(lexer: *lex::lexer) (ast::_type | error) = {
ast::len_slice => void,
* => want(lexer, ltok::RBRACKET)?,
};
-
+ let _type = _type(lexer)?;
return ast::_type {
- loc = start.2,
+ start = start.2,
+ end = lex::prevloc(lexer),
+ flags = 0,
_type = ast::list_type {
length = length,
- members = alloc(_type(lexer)?),
+ members = alloc(_type),
},
- ...
};
};
@@ -364,12 +380,13 @@ fn enum_type(lexer: *lex::lexer) (ast::_type | error) = {
};
return ast::_type {
- loc = start.2,
+ start = start.2,
+ end = lex::prevloc(lexer),
+ flags = 0,
_type = ast::enum_type {
storage = storage,
values = membs,
},
- ...
};
};
@@ -401,8 +418,8 @@ export fn _type(lexer: *lex::lexer) (ast::_type | error) = {
let t = _type(lexer)?;
switch (want(lexer, ltok::BOR,
ltok::COMMA)?.0) {
- ltok::BOR => tagged_type(lexer, t)?,
- ltok::COMMA => tuple_type(lexer, t)?,
+ ltok::BOR => tagged_type(lexer, t, tok.2)?,
+ ltok::COMMA => tuple_type(lexer, t, tok.2)?,
* => abort("unreachable"),
};
},
diff --git a/hare/unparse/decl.ha b/hare/unparse/decl.ha
@@ -104,12 +104,14 @@ fn decl_test(d: ast::decl, expected: str) bool = {
col = 0,
};
let type_int = ast::_type {
- loc = loc,
+ start = loc,
+ end = loc,
flags = 0,
_type = ast::builtin_type::INT,
};
let type_fn = ast::_type {
- loc = loc,
+ start = loc,
+ end = loc,
flags = ast::type_flags::CONST,
_type = ast::func_type {
result = &type_int,
diff --git a/hare/unparse/type.ha b/hare/unparse/type.ha
@@ -216,7 +216,8 @@ fn type_test(t: ast::_type, expected: str) bool = {
col = 0,
};
let t = ast::_type {
- loc = loc,
+ start = loc,
+ end = loc,
flags = ast::type_flags::CONST,
_type = ast::alias_type {
unwrap = false,
@@ -224,7 +225,8 @@ fn type_test(t: ast::_type, expected: str) bool = {
},
};
let type_int = ast::_type {
- loc = loc,
+ start = loc,
+ end = loc,
flags = 0,
_type = ast::builtin_type::INT,
};