hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mhare/ast/type.ha | 3++-
Mhare/parse/decl.ha | 6++++--
Mhare/parse/expr.ha | 6++++--
Mhare/parse/parse.ha | 8+++++---
Mhare/parse/type.ha | 67++++++++++++++++++++++++++++++++++++++++++-------------------------
Mhare/unparse/decl.ha | 6++++--
Mhare/unparse/type.ha | 6++++--
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, };