diff --git a/src/parser.pr b/src/parser.pr index 3dbc8f83..82cb2d2d 100644 --- a/src/parser.pr +++ b/src/parser.pr @@ -2396,11 +2396,24 @@ def expect_array_lit(parse_state: &ParseState) -> &Node { var token = peek(parse_state) let line = token.line let column = token.column + + // First try to parse [N; T} + var tokens = parse_state.tokens + var node = parse_array_n(parse_state) + if node { return node } + parse_state.tokens = tokens expect(parse_state, lexer::TokenType::O_SQUARE, "Expecting '['") var body = vector::make(type &Node) skip_newline(parse_state) token = peek(parse_state) + + // [var N] + if token.tpe == lexer::TokenType::K_VAR or token.tpe == lexer::TokenType::K_LET { + parse_state.tokens = tokens + return expect_array(parse_state) + } + if token.tpe != lexer::TokenType::C_SQUARE { loop { var expr = expect_expression_no_assign(parse_state) @@ -2419,7 +2432,7 @@ def expect_array_lit(parse_state: &ParseState) -> &Node { skip_newline(parse_state) expect(parse_state, lexer::TokenType::C_SQUARE, "Expecting ']'") - var node = make_node(NodeKind::ARRAY_LIT, line, column, parse_state) + node = make_node(NodeKind::ARRAY_LIT, line, column, parse_state) node.value.body = body node._hash = combine_hashes(node.kind !uint64, hash(body)) @@ -2767,7 +2780,17 @@ def parse_pre_expression(parse_state: &ParseState) -> &Node { } else if next_token(parse_state, lexer::TokenType::OP_SUB) { skip_newline(parse_state) return make_un_op(parse_state, token, NodeKind::USUB, parse_pre_expression(parse_state)) + } else if next_token(parse_state, lexer::TokenType::OP_BAND) { + // For now you can only use these as prefix expression, therefore we don't need to stay ambiguous + back(parse_state) + return expect_ptr_ref(parse_state, true, false) } else if next_token(parse_state, lexer::TokenType::OP_MUL) { + let next = peek(parse_state) + if next.tpe == lexer::TokenType::K_VAR or next.tpe == lexer::TokenType::K_LET { + // We definitely have a pointer in this case + back(parse_state) + return expect_ptr_ref(parse_state, false, false) + } skip_newline(parse_state) return make_un_op(parse_state, token, NodeKind::PTR, parse_pre_expression(parse_state)) } else if next_token(parse_state, lexer::TokenType::OP_DEREF) { diff --git a/src/typechecking.pr b/src/typechecking.pr index 5221c245..f8498cee 100644 --- a/src/typechecking.pr +++ b/src/typechecking.pr @@ -2318,6 +2318,17 @@ def convert_ambiguous_expr_to_type(node: &parser::Node, state: &State) -> &Type res.tpe = arr_tpe res.tpe.node = null + return res.tpe + } else if node.kind == parser::NodeKind::PTR { + var res = { kind = parser::NodeKind::PTR_T } !&parser::Node + res.value.t_parr.tpe = node.value.expr + res.value.t_parr.tpe.tpe = convert_ambiguous_expr_to_type(res.value.t_parr.tpe, state) + let ptr_tpe = make_type_raw(TypeKind::TYPE) + res.tpe = type_lookup(res, state) + ptr_tpe._tpe = res.tpe + res.tpe = ptr_tpe + res.tpe.node = null + return res.tpe } else if node.kind == parser::NodeKind::IDENTIFIER { return type_lookup(node, state) @@ -2950,10 +2961,9 @@ def walk_ArrayStaticT(node: &parser::Node, state: &State) { size = value.i } - let tpe = expr.svalue.value.value_tpe let tpe2 = copy(builtins::Type_) tpe2._tpe = type_lookup(node, state) - node.tpe = tpe2 + node.tpe = pointer(tpe2) } def walk_TypeOfT(node: &parser::Node, state: &State) { @@ -4902,6 +4912,10 @@ def walk_Ptr(node: &parser::Node, state: &State) { } node.tpe = pointer(tpe, tpe.kw) + + if equals(tpe, pointer(builtins::Type_)) or tpe.may_be_type { + node.tpe.may_be_type = convert_ambiguous_expr_to_type(node, state) + } } def walk_MemberAccess_ucs(node: &parser::Node, state: &State) -> bool {