mirror of
https://github.com/AleoHQ/leo.git
synced 2024-09-21 12:07:56 +03:00
Support NodeID in parser; note that NodeID::default() is a placeholder
This commit is contained in:
parent
5a1b9efd80
commit
a819488190
@ -19,6 +19,7 @@ use leo_span::Span;
|
||||
/// A node ID.
|
||||
// Development Note:
|
||||
// A `NodeID` must implement: `Copy`, `Default`, among others.
|
||||
// TODO (@d0cd): Replace use of `NodeID::default()` with unique IDs in the rest of the codebase.
|
||||
pub type NodeID = usize;
|
||||
|
||||
/// A node in the AST.
|
||||
|
@ -131,7 +131,7 @@ impl<'a> ParserContext<'a> {
|
||||
/// At the previous token, return and make an identifier with `name`.
|
||||
fn mk_ident_prev(&self, name: Symbol) -> Identifier {
|
||||
let span = self.prev_token.span;
|
||||
Identifier { name, span }
|
||||
Identifier { name, span, id: NodeID::default() }
|
||||
}
|
||||
|
||||
/// Eats the next token if its an identifier and returns it.
|
||||
|
@ -73,6 +73,7 @@ impl ParserContext<'_> {
|
||||
condition: Box::new(expr),
|
||||
if_true: Box::new(if_true),
|
||||
if_false: Box::new(if_false),
|
||||
id: NodeID::default(),
|
||||
});
|
||||
}
|
||||
Ok(expr)
|
||||
@ -85,6 +86,7 @@ impl ParserContext<'_> {
|
||||
op,
|
||||
left: Box::new(left),
|
||||
right: Box::new(right),
|
||||
id: NodeID::default(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -235,7 +237,7 @@ impl ParserContext<'_> {
|
||||
if self.eat(&Token::As) {
|
||||
let (type_, end_span) = self.parse_primitive_type()?;
|
||||
let span = expr.span() + end_span;
|
||||
expr = Expression::Cast(CastExpression { expression: Box::new(expr), type_, span });
|
||||
expr = Expression::Cast(CastExpression { expression: Box::new(expr), type_, span, id: NodeID::default() });
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
@ -261,19 +263,20 @@ impl ParserContext<'_> {
|
||||
// If the last operation is a negation and the inner expression is a literal, then construct a negative literal.
|
||||
if let Some((UnaryOperation::Negate, _)) = ops.last() {
|
||||
match inner {
|
||||
Expression::Literal(Literal::Integer(integer_type, string, span)) => {
|
||||
Expression::Literal(Literal::Integer(integer_type, string, span, id)) => {
|
||||
// Remove the negation from the operations.
|
||||
// Note that this unwrap is safe because there is at least one operation in `ops`.
|
||||
let (_, op_span) = ops.pop().unwrap();
|
||||
// Construct a negative integer literal.
|
||||
inner = Expression::Literal(Literal::Integer(integer_type, format!("-{string}"), op_span + span));
|
||||
inner =
|
||||
Expression::Literal(Literal::Integer(integer_type, format!("-{string}"), op_span + span, id));
|
||||
}
|
||||
Expression::Literal(Literal::Field(string, span)) => {
|
||||
Expression::Literal(Literal::Field(string, span, id)) => {
|
||||
// Remove the negation from the operations.
|
||||
// Note that
|
||||
let (_, op_span) = ops.pop().unwrap();
|
||||
// Construct a negative field literal.
|
||||
inner = Expression::Literal(Literal::Field(format!("-{string}"), op_span + span));
|
||||
inner = Expression::Literal(Literal::Field(format!("-{string}"), op_span + span, id));
|
||||
}
|
||||
Expression::Literal(Literal::Group(group_literal)) => {
|
||||
// Remove the negation from the operations.
|
||||
@ -281,17 +284,17 @@ impl ParserContext<'_> {
|
||||
// Construct a negative group literal.
|
||||
// Note that we only handle the case where the group literal is a single integral value.
|
||||
inner = Expression::Literal(Literal::Group(Box::new(match *group_literal {
|
||||
GroupLiteral::Single(string, span) => {
|
||||
GroupLiteral::Single(format!("-{string}"), op_span + span)
|
||||
GroupLiteral::Single(string, span, id) => {
|
||||
GroupLiteral::Single(format!("-{string}"), op_span + span, id)
|
||||
}
|
||||
GroupLiteral::Tuple(tuple) => GroupLiteral::Tuple(tuple),
|
||||
})));
|
||||
}
|
||||
Expression::Literal(Literal::Scalar(string, span)) => {
|
||||
Expression::Literal(Literal::Scalar(string, span, id)) => {
|
||||
// Remove the negation from the operations.
|
||||
let (_, op_span) = ops.pop().unwrap();
|
||||
// Construct a negative scalar literal.
|
||||
inner = Expression::Literal(Literal::Scalar(format!("-{string}"), op_span + span));
|
||||
inner = Expression::Literal(Literal::Scalar(format!("-{string}"), op_span + span, id));
|
||||
}
|
||||
_ => (), // Do nothing.
|
||||
}
|
||||
@ -299,7 +302,12 @@ impl ParserContext<'_> {
|
||||
|
||||
// Apply the operations in reverse order, constructing a unary expression.
|
||||
for (op, op_span) in ops.into_iter().rev() {
|
||||
inner = Expression::Unary(UnaryExpression { span: op_span + inner.span(), op, receiver: Box::new(inner) });
|
||||
inner = Expression::Unary(UnaryExpression {
|
||||
span: op_span + inner.span(),
|
||||
op,
|
||||
receiver: Box::new(inner),
|
||||
id: NodeID::default(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(inner)
|
||||
@ -315,7 +323,7 @@ impl ParserContext<'_> {
|
||||
|
||||
if let (true, Some(op)) = (args.is_empty(), UnaryOperation::from_symbol(method.name)) {
|
||||
// Found an unary operator and the argument list is empty.
|
||||
Ok(Expression::Unary(UnaryExpression { span, op, receiver: Box::new(receiver) }))
|
||||
Ok(Expression::Unary(UnaryExpression { span, op, receiver: Box::new(receiver), id: NodeID::default() }))
|
||||
} else if let (1, Some(op)) = (args.len(), BinaryOperation::from_symbol(method.name)) {
|
||||
// Found a binary operator and the argument list contains a single argument.
|
||||
Ok(Expression::Binary(BinaryExpression {
|
||||
@ -323,6 +331,7 @@ impl ParserContext<'_> {
|
||||
op,
|
||||
left: Box::new(receiver),
|
||||
right: Box::new(args.swap_remove(0)),
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
} else {
|
||||
// Attempt to parse the method call as a mapping operation.
|
||||
@ -342,12 +351,13 @@ impl ParserContext<'_> {
|
||||
arguments
|
||||
},
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
})))
|
||||
}
|
||||
_ => {
|
||||
// Either an invalid unary/binary operator, or more arguments given.
|
||||
self.emit_err(ParserError::invalid_method_call(receiver, method, args.len(), span));
|
||||
Ok(Expression::Err(ErrExpression { span }))
|
||||
Ok(Expression::Err(ErrExpression { span, id: NodeID::default() }))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -377,6 +387,7 @@ impl ParserContext<'_> {
|
||||
ty: type_,
|
||||
name: member_name,
|
||||
arguments: args,
|
||||
id: NodeID::default(),
|
||||
})
|
||||
} else {
|
||||
// Return the struct constant.
|
||||
@ -384,6 +395,7 @@ impl ParserContext<'_> {
|
||||
span: module_name.span() + member_name.span(),
|
||||
ty: type_,
|
||||
name: member_name,
|
||||
id: NodeID::default(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
@ -407,8 +419,12 @@ impl ParserContext<'_> {
|
||||
if self.check_int() {
|
||||
// Eat a tuple member access.
|
||||
let (index, span) = self.eat_integer()?;
|
||||
expr =
|
||||
Expression::Access(AccessExpression::Tuple(TupleAccess { tuple: Box::new(expr), index, span }))
|
||||
expr = Expression::Access(AccessExpression::Tuple(TupleAccess {
|
||||
tuple: Box::new(expr),
|
||||
index,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
} else if self.eat(&Token::Leo) {
|
||||
// Eat an external function call.
|
||||
self.eat(&Token::Div); // todo: Make `/` a more general token.
|
||||
@ -423,6 +439,7 @@ impl ParserContext<'_> {
|
||||
function: Box::new(Expression::Identifier(name)),
|
||||
external: Some(Box::new(expr)),
|
||||
arguments,
|
||||
id: NodeID::default(),
|
||||
});
|
||||
} else {
|
||||
// Parse identifier name.
|
||||
@ -437,6 +454,7 @@ impl ParserContext<'_> {
|
||||
span: expr.span() + name.span(),
|
||||
inner: Box::new(expr),
|
||||
name,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -451,6 +469,7 @@ impl ParserContext<'_> {
|
||||
function: Box::new(expr),
|
||||
external: None,
|
||||
arguments,
|
||||
id: NodeID::default(),
|
||||
});
|
||||
}
|
||||
// Check if next token is a dot to see if we are calling recursive method.
|
||||
@ -472,7 +491,7 @@ impl ParserContext<'_> {
|
||||
|
||||
match elements.len() {
|
||||
// If the tuple expression is empty, return a `UnitExpression`.
|
||||
0 => Ok(Expression::Unit(UnitExpression { span })),
|
||||
0 => Ok(Expression::Unit(UnitExpression { span, id: NodeID::default() })),
|
||||
1 => match trailing {
|
||||
// If there is one element in the tuple but no trailing comma, e.g `(foo)`, return the element.
|
||||
false => Ok(elements.swap_remove(0)),
|
||||
@ -481,7 +500,7 @@ impl ParserContext<'_> {
|
||||
},
|
||||
// Otherwise, return a tuple expression.
|
||||
// Note: This is the only place where `TupleExpression` is constructed in the parser.
|
||||
_ => Ok(Expression::Tuple(TupleExpression { elements, span })),
|
||||
_ => Ok(Expression::Tuple(TupleExpression { elements, span, id: NodeID::default() })),
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,7 +548,7 @@ impl ParserContext<'_> {
|
||||
let end_span = check_ahead(dist, &Token::Group)?;
|
||||
dist += 1; // Standing at `)` so advance one for 'group'.
|
||||
|
||||
let gt = GroupTuple { span: start_span + &end_span, x: first_gc, y: second_gc };
|
||||
let gt = GroupTuple { span: start_span + &end_span, x: first_gc, y: second_gc, id: NodeID::default() };
|
||||
|
||||
// Eat everything so that this isn't just peeking.
|
||||
for _ in 0..dist {
|
||||
@ -559,7 +578,7 @@ impl ParserContext<'_> {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(StructVariableInitializer { identifier, expression })
|
||||
Ok(StructVariableInitializer { identifier, expression, id: NodeID::default() })
|
||||
}
|
||||
|
||||
/// Returns an [`Expression`] AST node if the next tokens represent a
|
||||
@ -569,7 +588,12 @@ impl ParserContext<'_> {
|
||||
let (members, _, end) =
|
||||
self.parse_list(Delimiter::Brace, Some(Token::Comma), |p| p.parse_struct_member().map(Some))?;
|
||||
|
||||
Ok(Expression::Struct(StructExpression { span: identifier.span + end, name: identifier, members }))
|
||||
Ok(Expression::Struct(StructExpression {
|
||||
span: identifier.span + end,
|
||||
name: identifier,
|
||||
members,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
}
|
||||
|
||||
/// Returns an [`Expression`] AST node if the next token is a primary expression:
|
||||
@ -596,38 +620,42 @@ impl ParserContext<'_> {
|
||||
// Literal followed by `field`, e.g., `42field`.
|
||||
Some(Token::Field) => {
|
||||
assert_no_whitespace("field")?;
|
||||
Expression::Literal(Literal::Field(value, full_span))
|
||||
Expression::Literal(Literal::Field(value, full_span, NodeID::default()))
|
||||
}
|
||||
// Literal followed by `group`, e.g., `42group`.
|
||||
Some(Token::Group) => {
|
||||
assert_no_whitespace("group")?;
|
||||
Expression::Literal(Literal::Group(Box::new(GroupLiteral::Single(value, full_span))))
|
||||
Expression::Literal(Literal::Group(Box::new(GroupLiteral::Single(
|
||||
value,
|
||||
full_span,
|
||||
NodeID::default(),
|
||||
))))
|
||||
}
|
||||
// Literal followed by `scalar` e.g., `42scalar`.
|
||||
Some(Token::Scalar) => {
|
||||
assert_no_whitespace("scalar")?;
|
||||
Expression::Literal(Literal::Scalar(value, full_span))
|
||||
Expression::Literal(Literal::Scalar(value, full_span, NodeID::default()))
|
||||
}
|
||||
// Literal followed by other type suffix, e.g., `42u8`.
|
||||
Some(suffix) => {
|
||||
assert_no_whitespace(&suffix.to_string())?;
|
||||
let int_ty = Self::token_to_int_type(suffix).expect("unknown int type token");
|
||||
Expression::Literal(Literal::Integer(int_ty, value, full_span))
|
||||
Expression::Literal(Literal::Integer(int_ty, value, full_span, NodeID::default()))
|
||||
}
|
||||
None => return Err(ParserError::implicit_values_not_allowed(value, span).into()),
|
||||
}
|
||||
}
|
||||
Token::True => Expression::Literal(Literal::Boolean(true, span)),
|
||||
Token::False => Expression::Literal(Literal::Boolean(false, span)),
|
||||
Token::True => Expression::Literal(Literal::Boolean(true, span, NodeID::default())),
|
||||
Token::False => Expression::Literal(Literal::Boolean(false, span, NodeID::default())),
|
||||
Token::AddressLit(address_string) => {
|
||||
if address_string.parse::<Address<Testnet3>>().is_err() {
|
||||
self.emit_err(ParserError::invalid_address_lit(&address_string, span));
|
||||
}
|
||||
Expression::Literal(Literal::Address(address_string, span))
|
||||
Expression::Literal(Literal::Address(address_string, span, NodeID::default()))
|
||||
}
|
||||
Token::StaticString(value) => Expression::Literal(Literal::String(value, span)),
|
||||
Token::StaticString(value) => Expression::Literal(Literal::String(value, span, NodeID::default())),
|
||||
Token::Identifier(name) => {
|
||||
let ident = Identifier { name, span };
|
||||
let ident = Identifier { name, span, id: NodeID::default() };
|
||||
if !self.disallow_struct_construction && self.check(&Token::LeftCurly) {
|
||||
// Parse struct and records inits as struct expressions.
|
||||
// Enforce struct or record type later at type checking.
|
||||
@ -636,10 +664,12 @@ impl ParserContext<'_> {
|
||||
Expression::Identifier(ident)
|
||||
}
|
||||
}
|
||||
Token::SelfLower => Expression::Identifier(Identifier { name: sym::SelfLower, span }),
|
||||
Token::Block => Expression::Identifier(Identifier { name: sym::block, span }),
|
||||
Token::SelfLower => {
|
||||
Expression::Identifier(Identifier { name: sym::SelfLower, span, id: NodeID::default() })
|
||||
}
|
||||
Token::Block => Expression::Identifier(Identifier { name: sym::block, span, id: NodeID::default() }),
|
||||
t if crate::type_::TYPE_TOKENS.contains(&t) => {
|
||||
Expression::Identifier(Identifier { name: t.keyword_to_symbol().unwrap(), span })
|
||||
Expression::Identifier(Identifier { name: t.keyword_to_symbol().unwrap(), span, id: NodeID::default() })
|
||||
}
|
||||
token => {
|
||||
return Err(ParserError::unexpected_str(token, "expression", span).into());
|
||||
|
@ -223,7 +223,7 @@ impl ParserContext<'_> {
|
||||
|
||||
let (identifier, type_, span) = self.parse_typed_ident()?;
|
||||
|
||||
Ok(Member { mode, identifier, type_, span })
|
||||
Ok(Member { mode, identifier, type_, span, id: NodeID::default() })
|
||||
}
|
||||
|
||||
/// Parses a struct or record definition, e.g., `struct Foo { ... }` or `record Foo { ... }`.
|
||||
@ -235,7 +235,13 @@ impl ParserContext<'_> {
|
||||
self.expect(&Token::LeftCurly)?;
|
||||
let (members, end) = self.parse_struct_members()?;
|
||||
|
||||
Ok((struct_name.name, Struct { identifier: struct_name, members, is_record, span: start + end }))
|
||||
Ok((struct_name.name, Struct {
|
||||
identifier: struct_name,
|
||||
members,
|
||||
is_record,
|
||||
span: start + end,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parses a mapping declaration, e.g. `mapping balances: address => u128`.
|
||||
@ -247,7 +253,7 @@ impl ParserContext<'_> {
|
||||
self.expect(&Token::BigArrow)?;
|
||||
let (value_type, _) = self.parse_type()?;
|
||||
let end = self.expect(&Token::Semicolon)?;
|
||||
Ok((identifier.name, Mapping { identifier, key_type, value_type, span: start + end }))
|
||||
Ok((identifier.name, Mapping { identifier, key_type, value_type, span: start + end, id: NodeID::default() }))
|
||||
}
|
||||
|
||||
// TODO: Return a span associated with the mode.
|
||||
@ -298,11 +304,23 @@ impl ParserContext<'_> {
|
||||
self.eat(&Token::Record);
|
||||
span = span + self.prev_token.span;
|
||||
|
||||
Ok(functions::Input::External(External { identifier: name, program_name: external, record, span }))
|
||||
Ok(functions::Input::External(External {
|
||||
identifier: name,
|
||||
program_name: external,
|
||||
record,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
} else {
|
||||
let type_ = self.parse_type()?.0;
|
||||
|
||||
Ok(functions::Input::Internal(FunctionInput { identifier: name, mode, type_, span: name.span }))
|
||||
Ok(functions::Input::Internal(FunctionInput {
|
||||
identifier: name,
|
||||
mode,
|
||||
type_,
|
||||
span: name.span,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,7 +329,7 @@ impl ParserContext<'_> {
|
||||
// TODO: Could this span be made more accurate?
|
||||
let mode = self.parse_mode()?;
|
||||
let (type_, span) = self.parse_type()?;
|
||||
Ok(FunctionOutput { mode, type_, span })
|
||||
Ok(FunctionOutput { mode, type_, span, id: NodeID::default() })
|
||||
}
|
||||
|
||||
/// Returns a [`Output`] AST node if the next tokens represent a function output.
|
||||
@ -338,6 +356,7 @@ impl ParserContext<'_> {
|
||||
program_name: external,
|
||||
record,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
} else {
|
||||
Ok(Output::Internal(self.parse_function_output()?))
|
||||
@ -353,7 +372,9 @@ impl ParserContext<'_> {
|
||||
// Parse the `@` symbol and identifier.
|
||||
let start = self.expect(&Token::At)?;
|
||||
let identifier = match self.token.token {
|
||||
Token::Program => Identifier { name: sym::program, span: self.expect(&Token::Program)? },
|
||||
Token::Program => {
|
||||
Identifier { name: sym::program, span: self.expect(&Token::Program)?, id: NodeID::default() }
|
||||
}
|
||||
_ => self.expect_identifier()?,
|
||||
};
|
||||
let span = start + identifier.span;
|
||||
@ -362,7 +383,7 @@ impl ParserContext<'_> {
|
||||
// Check that there is no whitespace in between the `@` symbol and identifier.
|
||||
match identifier.span.hi.0 - start.lo.0 > 1 + identifier.name.to_string().len() as u32 {
|
||||
true => Err(ParserError::space_in_annotation(span).into()),
|
||||
false => Ok(Annotation { identifier, span }),
|
||||
false => Ok(Annotation { identifier, span, id: NodeID::default() }),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ impl ParserContext<'_> {
|
||||
self.expect(&Token::Semicolon)?;
|
||||
|
||||
// Return the assertion statement.
|
||||
Ok(Statement::Assert(AssertStatement { variant, span }))
|
||||
Ok(Statement::Assert(AssertStatement { variant, span, id: NodeID::default() }))
|
||||
}
|
||||
|
||||
/// Returns a [`AssignStatement`] AST node if the next tokens represent a assign, otherwise expects an expression statement.
|
||||
@ -124,10 +124,11 @@ impl ParserContext<'_> {
|
||||
right: Box::new(value),
|
||||
op,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
}),
|
||||
};
|
||||
|
||||
Ok(Statement::Assign(Box::new(AssignStatement { span, place, value })))
|
||||
Ok(Statement::Assign(Box::new(AssignStatement { span, place, value, id: NodeID::default() })))
|
||||
} else {
|
||||
// Check for `increment` and `decrement` statements. If found, emit a deprecation warning.
|
||||
if let Expression::Call(call_expression) = &place {
|
||||
@ -152,14 +153,21 @@ impl ParserContext<'_> {
|
||||
|
||||
// Parse the expression as a statement.
|
||||
let end = self.expect(&Token::Semicolon)?;
|
||||
Ok(Statement::Expression(ExpressionStatement { span: place.span() + end, expression: place }))
|
||||
Ok(Statement::Expression(ExpressionStatement {
|
||||
span: place.span() + end,
|
||||
expression: place,
|
||||
id: NodeID::default(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a [`Block`] AST node if the next tokens represent a block of statements.
|
||||
pub(super) fn parse_block(&mut self) -> Result<Block> {
|
||||
self.parse_list(Delimiter::Brace, None, |p| p.parse_statement().map(Some))
|
||||
.map(|(statements, _, span)| Block { statements, span })
|
||||
self.parse_list(Delimiter::Brace, None, |p| p.parse_statement().map(Some)).map(|(statements, _, span)| Block {
|
||||
statements,
|
||||
span,
|
||||
id: NodeID::default(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a [`ReturnStatement`] AST node if the next tokens represent a return statement.
|
||||
@ -168,7 +176,9 @@ impl ParserContext<'_> {
|
||||
|
||||
let expression = match self.token.token {
|
||||
// If the next token is a semicolon, implicitly return a unit expression, `()`.
|
||||
Token::Semicolon | Token::Then => Expression::Unit(UnitExpression { span: self.token.span }),
|
||||
Token::Semicolon | Token::Then => {
|
||||
Expression::Unit(UnitExpression { span: self.token.span, id: NodeID::default() })
|
||||
}
|
||||
// Otherwise, attempt to parse an expression.
|
||||
_ => self.parse_expression()?,
|
||||
};
|
||||
@ -190,7 +200,7 @@ impl ParserContext<'_> {
|
||||
};
|
||||
let end = self.expect(&Token::Semicolon)?;
|
||||
let span = start + end;
|
||||
Ok(ReturnStatement { span, expression, finalize_arguments: finalize_args })
|
||||
Ok(ReturnStatement { span, expression, finalize_arguments: finalize_args, id: NodeID::default() })
|
||||
}
|
||||
|
||||
/// Returns a [`ConditionalStatement`] AST node if the next tokens represent a conditional statement.
|
||||
@ -215,6 +225,7 @@ impl ParserContext<'_> {
|
||||
condition: expr,
|
||||
then: body,
|
||||
otherwise: next,
|
||||
id: NodeID::default(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -245,6 +256,7 @@ impl ParserContext<'_> {
|
||||
stop_value: Default::default(),
|
||||
inclusive: false,
|
||||
block,
|
||||
id: NodeID::default(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -286,13 +298,16 @@ impl ParserContext<'_> {
|
||||
));
|
||||
(
|
||||
Default::default(),
|
||||
ConsoleFunction::Assert(Expression::Err(ErrExpression { span: Default::default() })),
|
||||
ConsoleFunction::Assert(Expression::Err(ErrExpression {
|
||||
span: Default::default(),
|
||||
id: NodeID::default(),
|
||||
})),
|
||||
)
|
||||
}
|
||||
};
|
||||
self.expect(&Token::Semicolon)?;
|
||||
|
||||
Ok(ConsoleStatement { span: keyword + span, function })
|
||||
Ok(ConsoleStatement { span: keyword + span, function, id: NodeID::default() })
|
||||
}
|
||||
|
||||
/// Returns a [`DefinitionStatement`] AST node if the next tokens represent a definition statement.
|
||||
@ -314,6 +329,13 @@ impl ParserContext<'_> {
|
||||
let value = self.parse_expression()?;
|
||||
self.expect(&Token::Semicolon)?;
|
||||
|
||||
Ok(DefinitionStatement { span: decl_span + value.span(), declaration_type: decl_type, place, type_, value })
|
||||
Ok(DefinitionStatement {
|
||||
span: decl_span + value.span(),
|
||||
declaration_type: decl_type,
|
||||
place,
|
||||
type_,
|
||||
value,
|
||||
id: NodeID::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user