Fix tests and refine new parsing

This commit is contained in:
Jeff 2024-06-17 15:47:07 -04:00
parent dbabf874b7
commit d53ddd07eb
13 changed files with 234 additions and 187 deletions

View File

@ -72,13 +72,13 @@ mod tests {
#[test] #[test]
fn run_returns_value_of_final_statement() { fn run_returns_value_of_final_statement() {
let block = Block::new(vec![ let block = Block::new(vec![
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(1).with_position((0, 0)), ValueNode::Integer(1).with_position((0, 0)),
)), )),
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(2).with_position((0, 0)), ValueNode::Integer(2).with_position((0, 0)),
)), )),
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(42).with_position((0, 0)), ValueNode::Integer(42).with_position((0, 0)),
)), )),
]); ]);
@ -92,10 +92,10 @@ mod tests {
#[test] #[test]
fn expected_type_returns_type_of_final_statement() { fn expected_type_returns_type_of_final_statement() {
let block = Block::new(vec![ let block = Block::new(vec![
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("42".to_string()).with_position((0, 0)), ValueNode::String("42".to_string()).with_position((0, 0)),
)), )),
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(42).with_position((0, 0)), ValueNode::Integer(42).with_position((0, 0)),
)), )),
]); ]);

View File

@ -168,7 +168,7 @@ mod tests {
assert_eq!( assert_eq!(
IfElse::new( IfElse::new(
Expression::Value(ValueNode::Boolean(true).with_position((0, 0))), Expression::Value(ValueNode::Boolean(true).with_position((0, 0))),
Block::new(vec![Statement::ValueExpression(Expression::Value( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string()).with_position((0, 0)) ValueNode::String("foo".to_string()).with_position((0, 0))
))]) ))])
.with_position((0, 0)), .with_position((0, 0)),

View File

@ -20,7 +20,7 @@ pub enum Statement {
Loop(WithPosition<Loop>), Loop(WithPosition<Loop>),
StructureDefinition(WithPosition<StructureDefinition>), StructureDefinition(WithPosition<StructureDefinition>),
TypeAssignment(WithPosition<TypeAssignment>), TypeAssignment(WithPosition<TypeAssignment>),
ValueExpression(Expression), Expression(Expression),
While(WithPosition<While>), While(WithPosition<While>),
} }
@ -31,7 +31,7 @@ impl Statement {
Statement::AsyncBlock(inner) => inner.position, Statement::AsyncBlock(inner) => inner.position,
Statement::Block(inner) => inner.position, Statement::Block(inner) => inner.position,
Statement::Break(inner) => inner.position, Statement::Break(inner) => inner.position,
Statement::ValueExpression(expression) => expression.position(), Statement::Expression(expression) => expression.position(),
Statement::IfElse(inner) => inner.position, Statement::IfElse(inner) => inner.position,
Statement::Loop(inner) => inner.position, Statement::Loop(inner) => inner.position,
Statement::StructureDefinition(inner) => inner.position, Statement::StructureDefinition(inner) => inner.position,
@ -54,7 +54,7 @@ impl AbstractNode for Statement {
} }
Statement::Block(block) => block.node.validate(_context, _manage_memory), Statement::Block(block) => block.node.validate(_context, _manage_memory),
Statement::Break(_) => Ok(()), Statement::Break(_) => Ok(()),
Statement::ValueExpression(expression) => expression.validate(_context, _manage_memory), Statement::Expression(expression) => expression.validate(_context, _manage_memory),
Statement::IfElse(if_else) => if_else.node.validate(_context, _manage_memory), Statement::IfElse(if_else) => if_else.node.validate(_context, _manage_memory),
Statement::Loop(r#loop) => r#loop.node.validate(_context, _manage_memory), Statement::Loop(r#loop) => r#loop.node.validate(_context, _manage_memory),
Statement::StructureDefinition(structure_definition) => { Statement::StructureDefinition(structure_definition) => {
@ -77,7 +77,7 @@ impl AbstractNode for Statement {
Statement::AsyncBlock(async_block) => async_block.node.evaluate(context, manage_memory), Statement::AsyncBlock(async_block) => async_block.node.evaluate(context, manage_memory),
Statement::Block(block) => block.node.evaluate(context, manage_memory), Statement::Block(block) => block.node.evaluate(context, manage_memory),
Statement::Break(_) => Ok(Evaluation::Break), Statement::Break(_) => Ok(Evaluation::Break),
Statement::ValueExpression(expression) => expression.evaluate(context, manage_memory), Statement::Expression(expression) => expression.evaluate(context, manage_memory),
Statement::IfElse(if_else) => if_else.node.evaluate(context, manage_memory), Statement::IfElse(if_else) => if_else.node.evaluate(context, manage_memory),
Statement::Loop(r#loop) => r#loop.node.evaluate(context, manage_memory), Statement::Loop(r#loop) => r#loop.node.evaluate(context, manage_memory),
Statement::StructureDefinition(structure_definition) => { Statement::StructureDefinition(structure_definition) => {
@ -100,7 +100,7 @@ impl AbstractNode for Statement {
impl ExpectedType for Statement { impl ExpectedType for Statement {
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
match self { match self {
Statement::ValueExpression(expression) => expression.expected_type(_context), Statement::Expression(expression) => expression.expected_type(_context),
Statement::IfElse(if_else) => if_else.node.expected_type(_context), Statement::IfElse(if_else) => if_else.node.expected_type(_context),
Statement::Block(block) => block.node.expected_type(_context), Statement::Block(block) => block.node.expected_type(_context),
Statement::AsyncBlock(async_block) => async_block.node.expected_type(_context), Statement::AsyncBlock(async_block) => async_block.node.expected_type(_context),

View File

@ -18,7 +18,7 @@ pub enum TypeConstructor {
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct FunctionTypeConstructor { pub struct FunctionTypeConstructor {
pub type_parameters: Option<Vec<WithPosition<Identifier>>>, pub type_parameters: Option<Vec<WithPosition<Identifier>>>,
pub value_parameters: Vec<(WithPosition<Identifier>, Box<TypeConstructor>)>, pub value_parameters: Vec<TypeConstructor>,
pub return_type: Box<TypeConstructor>, pub return_type: Box<TypeConstructor>,
} }
@ -72,8 +72,12 @@ impl TypeConstructor {
item_type: Box::new(constructed_type), item_type: Box::new(constructed_type),
}) })
} }
TypeConstructor::ListOf(item_type) => {
let item_type = item_type.node.construct(&context)?;
Ok(Type::ListOf(Box::new(item_type)))
}
TypeConstructor::Type(r#type) => Ok(r#type.node), TypeConstructor::Type(r#type) => Ok(r#type.node),
TypeConstructor::ListOf(_) => todo!(),
} }
} }
} }

View File

@ -26,8 +26,8 @@ pub enum ValueNode {
name: WithPosition<Identifier>, name: WithPosition<Identifier>,
fields: Vec<(WithPosition<Identifier>, Expression)>, fields: Vec<(WithPosition<Identifier>, Expression)>,
}, },
ParsedFunction { Parsed {
type_parameters: Option<Vec<WithPosition<Identifier>>>, type_parameters: Option<Vec<Identifier>>,
value_parameters: Vec<(Identifier, TypeConstructor)>, value_parameters: Vec<(Identifier, TypeConstructor)>,
return_type: TypeConstructor, return_type: TypeConstructor,
body: WithPosition<Block>, body: WithPosition<Block>,
@ -57,7 +57,7 @@ impl AbstractNode for ValueNode {
return Ok(()); return Ok(());
} }
if let ValueNode::ParsedFunction { if let ValueNode::Parsed {
type_parameters: _, type_parameters: _,
value_parameters, value_parameters,
return_type, return_type,
@ -175,7 +175,7 @@ impl AbstractNode for ValueNode {
} }
ValueNode::Range(range) => Value::range(range), ValueNode::Range(range) => Value::range(range),
ValueNode::String(string) => Value::string(string), ValueNode::String(string) => Value::string(string),
ValueNode::ParsedFunction { ValueNode::Parsed {
type_parameters, type_parameters,
value_parameters: constructors, value_parameters: constructors,
return_type, return_type,
@ -184,7 +184,7 @@ impl AbstractNode for ValueNode {
let type_parameters = type_parameters.map(|parameter_list| { let type_parameters = type_parameters.map(|parameter_list| {
parameter_list parameter_list
.into_iter() .into_iter()
.map(|parameter| parameter.node) .map(|parameter| parameter)
.collect() .collect()
}); });
let mut value_parameters = Vec::with_capacity(constructors.len()); let mut value_parameters = Vec::with_capacity(constructors.len());
@ -263,13 +263,13 @@ impl Ord for ValueNode {
(String(left), String(right)) => left.cmp(right), (String(left), String(right)) => left.cmp(right),
(String(_), _) => Ordering::Greater, (String(_), _) => Ordering::Greater,
( (
ParsedFunction { Parsed {
type_parameters: left_type_arguments, type_parameters: left_type_arguments,
value_parameters: left_parameters, value_parameters: left_parameters,
return_type: left_return, return_type: left_return,
body: left_body, body: left_body,
}, },
ParsedFunction { Parsed {
type_parameters: right_type_arguments, type_parameters: right_type_arguments,
value_parameters: right_parameters, value_parameters: right_parameters,
return_type: right_return, return_type: right_return,
@ -296,7 +296,7 @@ impl Ord for ValueNode {
parameter_cmp parameter_cmp
} }
} }
(ParsedFunction { .. }, _) => Ordering::Greater, (Parsed { .. }, _) => Ordering::Greater,
( (
Structure { Structure {
name: left_name, name: left_name,
@ -337,7 +337,7 @@ impl ExpectedType for ValueNode {
ValueNode::Map(_) => Type::Map, ValueNode::Map(_) => Type::Map,
ValueNode::Range(_) => Type::Range, ValueNode::Range(_) => Type::Range,
ValueNode::String(_) => Type::String, ValueNode::String(_) => Type::String,
ValueNode::ParsedFunction { ValueNode::Parsed {
type_parameters, type_parameters,
value_parameters, value_parameters,
return_type, return_type,
@ -354,7 +354,7 @@ impl ExpectedType for ValueNode {
let type_parameters = type_parameters.clone().map(|parameters| { let type_parameters = type_parameters.clone().map(|parameters| {
parameters parameters
.iter() .iter()
.map(|identifier| identifier.node.clone()) .map(|identifier| identifier.clone())
.collect() .collect()
}); });
let return_type = return_type.clone().construct(&context)?; let return_type = return_type.clone().construct(&context)?;

View File

@ -81,22 +81,13 @@ pub fn parser<'src>(
positioned_identifier positioned_identifier
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.collect() .at_least(1)
.delimited_by( .collect(),
just(Token::Control(Control::ParenOpen)),
just(Token::Control(Control::ParenClose)),
) )
.or_not(), .or_not()
)
.then(
positioned_identifier
.clone()
.then_ignore(just(Token::Control(Control::Colon)))
.then( .then(
type_constructor type_constructor
.clone() .clone()
.map(|constructor| Box::new(constructor)),
)
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.collect() .collect()
.delimited_by( .delimited_by(
@ -119,8 +110,7 @@ pub fn parser<'src>(
}, },
); );
let list = type_constructor let list_type = type_constructor
.clone()
.clone() .clone()
.then_ignore(just(Token::Control(Control::Semicolon))) .then_ignore(just(Token::Control(Control::Semicolon)))
.then(raw_integer.clone()) .then(raw_integer.clone())
@ -138,16 +128,27 @@ pub fn parser<'src>(
) )
}); });
let list_of = just(Token::Keyword(Keyword::List)) let list_of_type = type_constructor
.ignore_then(type_constructor.clone().delimited_by( .clone()
just(Token::Control(Control::ParenOpen)), .delimited_by(
just(Token::Control(Control::ParenClose)), just(Token::Control(Control::SquareOpen)),
)) just(Token::Control(Control::SquareClose)),
)
.map_with(|item_type, state| { .map_with(|item_type, state| {
TypeConstructor::ListOf(Box::new(item_type).with_position(state.span())) TypeConstructor::ListOf(Box::new(item_type).with_position(state.span()))
}); });
choice((function_type, list, list_of, primitive_type)) let identifier_type = positioned_identifier
.clone()
.map(|identifier| TypeConstructor::Identifier(identifier));
choice((
function_type,
list_type,
list_of_type,
primitive_type,
identifier_type,
))
}); });
let type_specification = let type_specification =
@ -195,23 +196,44 @@ pub fn parser<'src>(
Expression::Value(ValueNode::List(list).with_position(state.span())) Expression::Value(ValueNode::List(list).with_position(state.span()))
}); });
let parsed_function = just(Token::Keyword(Keyword::Fn)) let map_fields = identifier
.ignore_then(
positioned_identifier
.clone() .clone()
.separated_by(just(Token::Control(Control::Comma))) .then(type_specification.clone().or_not())
.then_ignore(just(Token::Operator(Operator::Assign)))
.then(expression.clone())
.map(|((identifier, r#type), expression)| (identifier, r#type, expression));
let map = map_fields
.separated_by(just(Token::Control(Control::Comma)).or_not())
.allow_trailing()
.collect() .collect()
.delimited_by( .delimited_by(
just(Token::Control(Control::ParenOpen)), just(Token::Control(Control::CurlyOpen)),
just(Token::Control(Control::ParenClose)), just(Token::Control(Control::CurlyClose)),
) )
.map_with(|map_assigment_list, state| {
Expression::Value(
ValueNode::Map(map_assigment_list).with_position(state.span()),
)
});
let function = just(Token::Keyword(Keyword::Fn))
.ignore_then(
identifier
.clone()
.separated_by(just(Token::Control(Control::Comma)))
.at_least(1)
.allow_trailing()
.collect()
.or_not(), .or_not(),
) )
.then( .then(
identifier identifier
.clone()
.then_ignore(just(Token::Control(Control::Colon))) .then_ignore(just(Token::Control(Control::Colon)))
.then(type_constructor.clone()) .then(type_constructor.clone())
.separated_by(just(Token::Control(Control::Comma))) .separated_by(just(Token::Control(Control::Comma)))
.allow_trailing()
.collect() .collect()
.delimited_by( .delimited_by(
just(Token::Control(Control::ParenOpen)), just(Token::Control(Control::ParenOpen)),
@ -224,7 +246,7 @@ pub fn parser<'src>(
.map_with( .map_with(
|(((type_parameters, value_parameters), return_type), body), state| { |(((type_parameters, value_parameters), return_type), body), state| {
Expression::Value( Expression::Value(
ValueNode::ParsedFunction { ValueNode::Parsed {
type_parameters, type_parameters,
value_parameters, value_parameters,
return_type, return_type,
@ -310,8 +332,9 @@ pub fn parser<'src>(
let atom = choice(( let atom = choice((
range.clone(), range.clone(),
parsed_function.clone(), function.clone(),
list.clone(), list.clone(),
map.clone(),
basic_value.clone(), basic_value.clone(),
identifier_expression.clone(), identifier_expression.clone(),
expression.clone().delimited_by( expression.clone().delimited_by(
@ -321,6 +344,7 @@ pub fn parser<'src>(
)); ));
let logic_math_indexes_as_and_function_calls = atom.pratt(( let logic_math_indexes_as_and_function_calls = atom.pratt((
// Logic
prefix( prefix(
2, 2,
just(Token::Operator(Operator::Not)), just(Token::Operator(Operator::Not)),
@ -340,15 +364,6 @@ pub fn parser<'src>(
) )
}, },
), ),
infix(
left(4),
just(Token::Control(Control::Dot)),
|left: Expression, _: Token, right: Expression, span| {
Expression::MapIndex(
Box::new(MapIndex::new(left, right)).with_position(span),
)
},
),
postfix( postfix(
3, 3,
turbofish.clone().or_not().then( turbofish.clone().or_not().then(
@ -434,6 +449,7 @@ pub fn parser<'src>(
Expression::Logic(Box::new(Logic::Or(left, right)).with_position(span)) Expression::Logic(Box::new(Logic::Or(left, right)).with_position(span))
}, },
), ),
// Math
infix( infix(
left(1), left(1),
just(Token::Operator(Operator::Add)), just(Token::Operator(Operator::Add)),
@ -469,6 +485,17 @@ pub fn parser<'src>(
Expression::Math(Box::new(Math::Modulo(left, right)).with_position(span)) Expression::Math(Box::new(Math::Modulo(left, right)).with_position(span))
}, },
), ),
// Indexes
infix(
left(4),
just(Token::Control(Control::Dot)),
|left, _, right, span| {
Expression::MapIndex(
Box::new(MapIndex::new(left, right)).with_position(span),
)
},
),
// As
postfix( postfix(
2, 2,
just(Token::Keyword(Keyword::As)).ignore_then(type_constructor.clone()), just(Token::Keyword(Keyword::As)).ignore_then(type_constructor.clone()),
@ -484,8 +511,9 @@ pub fn parser<'src>(
logic_math_indexes_as_and_function_calls, logic_math_indexes_as_and_function_calls,
built_in_function_call, built_in_function_call,
range, range,
parsed_function, function,
list, list,
map,
basic_value, basic_value,
identifier_expression, identifier_expression,
)) ))
@ -493,7 +521,7 @@ pub fn parser<'src>(
let expression_statement = expression let expression_statement = expression
.clone() .clone()
.map(|expression| Statement::ValueExpression(expression)); .map(|expression| Statement::Expression(expression));
let async_block = just(Token::Keyword(Keyword::Async)) let async_block = just(Token::Keyword(Keyword::Async))
.ignore_then(statement.clone().repeated().collect().delimited_by( .ignore_then(statement.clone().repeated().collect().delimited_by(
@ -630,7 +658,7 @@ mod tests {
fn r#as() { fn r#as() {
assert_eq!( assert_eq!(
parse(&lex("1 as str").unwrap()).unwrap()[0], parse(&lex("1 as str").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::As( Statement::Expression(Expression::As(
Box::new(As::new( Box::new(As::new(
Expression::Value(ValueNode::Integer(1).with_position((0, 1))), Expression::Value(ValueNode::Integer(1).with_position((0, 1))),
TypeConstructor::Type(Type::String.with_position((5, 8))) TypeConstructor::Type(Type::String.with_position((5, 8)))
@ -656,7 +684,7 @@ mod tests {
assert_eq!( assert_eq!(
statements[0], statements[0],
Statement::ValueExpression(Expression::BuiltInFunctionCall( Statement::Expression(Expression::BuiltInFunctionCall(
Box::new(BuiltInFunctionCall::ReadLine).with_position((0, 9)) Box::new(BuiltInFunctionCall::ReadLine).with_position((0, 9))
)) ))
); );
@ -675,7 +703,7 @@ mod tests {
assert_eq!( assert_eq!(
statements[0], statements[0],
Statement::ValueExpression(Expression::BuiltInFunctionCall( Statement::Expression(Expression::BuiltInFunctionCall(
Box::new(BuiltInFunctionCall::WriteLine(Expression::Value( Box::new(BuiltInFunctionCall::WriteLine(Expression::Value(
ValueNode::String("hiya".to_string()).with_position((11, 17)) ValueNode::String("hiya".to_string()).with_position((11, 17))
))) )))
@ -700,13 +728,13 @@ mod tests {
.unwrap()[0], .unwrap()[0],
Statement::AsyncBlock( Statement::AsyncBlock(
AsyncBlock::new(vec![ AsyncBlock::new(vec![
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(1).with_position((53, 54)) ValueNode::Integer(1).with_position((53, 54))
)), )),
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(2).with_position((79, 80)) ValueNode::Integer(2).with_position((79, 80))
)), )),
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(3).with_position((105, 106)) ValueNode::Integer(3).with_position((105, 106))
)), )),
]) ])
@ -728,7 +756,7 @@ mod tests {
.unwrap() .unwrap()
) )
.unwrap()[0], .unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Structure { ValueNode::Structure {
name: Identifier::new("Foo").with_position((21, 24)), name: Identifier::new("Foo").with_position((21, 24)),
fields: vec![ fields: vec![
@ -785,7 +813,7 @@ mod tests {
fn map_index() { fn map_index() {
assert_eq!( assert_eq!(
parse(&lex("{ x = 42 }.x").unwrap()).unwrap()[0], parse(&lex("{ x = 42 }.x").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::MapIndex( Statement::Expression(Expression::MapIndex(
Box::new(MapIndex::new( Box::new(MapIndex::new(
Expression::Value( Expression::Value(
ValueNode::Map(vec![( ValueNode::Map(vec![(
@ -802,7 +830,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
parse(&lex("foo.x").unwrap()).unwrap()[0], parse(&lex("foo.x").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::MapIndex( Statement::Expression(Expression::MapIndex(
Box::new(MapIndex::new( Box::new(MapIndex::new(
Expression::Identifier(Identifier::new("foo").with_position((0, 3))), Expression::Identifier(Identifier::new("foo").with_position((0, 3))),
Expression::Identifier(Identifier::new("x").with_position((4, 5))) Expression::Identifier(Identifier::new("x").with_position((4, 5)))
@ -819,12 +847,12 @@ mod tests {
Statement::While( Statement::While(
While::new( While::new(
Expression::Value(ValueNode::Boolean(true).with_position((6, 10))), Expression::Value(ValueNode::Boolean(true).with_position((6, 10))),
vec![Statement::ValueExpression(Expression::FunctionCall( vec![Statement::Expression(Expression::FunctionCall(
FunctionCall::new( FunctionCall::new(
Expression::Identifier( Expression::Identifier(
Identifier::new("output").with_position((13, 19)) Identifier::new("output").with_position((13, 19))
), ),
Some(Vec::with_capacity(0)), None,
vec![Expression::Value( vec![Expression::Value(
ValueNode::String("hi".to_string()).with_position((20, 24)) ValueNode::String("hi".to_string()).with_position((20, 24))
)] )]
@ -844,9 +872,9 @@ mod tests {
Statement::Assignment( Statement::Assignment(
Assignment::new( Assignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some(TypeConstructor::Type(Type::Boolean.with_position((0, 0)))), Some(TypeConstructor::Type(Type::Boolean.with_position((9, 13)))),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Boolean(true).with_position((16, 20)) ValueNode::Boolean(true).with_position((16, 20))
)) ))
) )
@ -866,17 +894,17 @@ mod tests {
ListTypeConstructor { ListTypeConstructor {
length: 2, length: 2,
item_type: Box::new(TypeConstructor::Type( item_type: Box::new(TypeConstructor::Type(
Type::Integer.with_position((0, 0)) Type::Integer.with_position((9, 12))
)) ))
} }
.with_position((8, 12)) .with_position((8, 16))
)), )),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::List(vec![]).with_position((15, 17)) ValueNode::List(vec![]).with_position((19, 21))
)) ))
) )
.with_position((0, 17)) .with_position((0, 21))
) )
); );
} }
@ -893,7 +921,7 @@ mod tests {
.with_position((0, 0)) .with_position((0, 0))
)), )),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::List(vec![Expression::Value( ValueNode::List(vec![Expression::Value(
ValueNode::Boolean(true).with_position((23, 27)) ValueNode::Boolean(true).with_position((23, 27))
)]) )])
@ -908,26 +936,26 @@ mod tests {
#[test] #[test]
fn function_type() { fn function_type() {
assert_eq!( assert_eq!(
parse(&lex("foobar : fn() -> any = some_function").unwrap()).unwrap()[0], parse(&lex("type Foo = fn T (int) -> T").unwrap()).unwrap()[0],
Statement::Assignment( Statement::TypeAssignment(
Assignment::new( TypeAssignment::new(
Identifier::new("foobar").with_position((0, 6)), Identifier::new("Foo").with_position((5, 8)),
Some(TypeConstructor::Function( TypeConstructor::Function(
FunctionTypeConstructor { FunctionTypeConstructor {
type_parameters: None, type_parameters: Some(vec![
value_parameters: vec![], Identifier::new("T").with_position((14, 15))
return_type: Box::new(TypeConstructor::Type( ]),
Type::Any.with_position((0, 0)) value_parameters: vec![TypeConstructor::Type(
Type::Integer.with_position((17, 20))
)],
return_type: Box::new(TypeConstructor::Identifier(
Identifier::new("T").with_position((25, 26))
)), )),
} }
.with_position((9, 20)) .with_position((11, 26))
)),
AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Identifier(
Identifier::new("some_function").with_position((23, 36))
))
) )
.with_position((0, 36)) )
.with_position((0, 26))
) )
); );
} }
@ -936,10 +964,10 @@ mod tests {
fn function_call() { fn function_call() {
assert_eq!( assert_eq!(
parse(&lex("foobar()").unwrap()).unwrap()[0], parse(&lex("foobar()").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::FunctionCall( Statement::Expression(Expression::FunctionCall(
FunctionCall::new( FunctionCall::new(
Expression::Identifier(Identifier::new("foobar").with_position((0, 6))), Expression::Identifier(Identifier::new("foobar").with_position((0, 6))),
Some(Vec::with_capacity(0)), None,
Vec::with_capacity(0), Vec::with_capacity(0),
) )
.with_position((0, 8)) .with_position((0, 8))
@ -951,7 +979,7 @@ mod tests {
fn function_call_with_type_arguments() { fn function_call_with_type_arguments() {
assert_eq!( assert_eq!(
parse(&lex("foobar::(str)::('hi')").unwrap()).unwrap()[0], parse(&lex("foobar::(str)::('hi')").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::FunctionCall( Statement::Expression(Expression::FunctionCall(
FunctionCall::new( FunctionCall::new(
Expression::Identifier(Identifier::new("foobar").with_position((0, 6))), Expression::Identifier(Identifier::new("foobar").with_position((0, 6))),
Some(vec![TypeConstructor::Type( Some(vec![TypeConstructor::Type(
@ -970,7 +998,7 @@ mod tests {
fn range() { fn range() {
assert_eq!( assert_eq!(
parse(&lex("1..10").unwrap()).unwrap()[0], parse(&lex("1..10").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Range(1..10).with_position((0, 5)) ValueNode::Range(1..10).with_position((0, 5))
)) ))
) )
@ -979,58 +1007,71 @@ mod tests {
#[test] #[test]
fn function() { fn function() {
assert_eq!( assert_eq!(
parse(&lex("fn (x: int) int { x }").unwrap()).unwrap()[0], parse(&lex("fn () -> int { 0 }").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::ParsedFunction { ValueNode::Parsed {
type_parameters: None,
value_parameters: vec![],
return_type: TypeConstructor::Type(Type::Integer.with_position((9, 12))),
body: Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::Integer(0).with_position((15, 16))
))])
.with_position((13, 18))
}
.with_position((0, 18))
),)
);
assert_eq!(
parse(&lex("fn (x: int) -> int { x }").unwrap()).unwrap()[0],
Statement::Expression(Expression::Value(
ValueNode::Parsed {
type_parameters: None, type_parameters: None,
value_parameters: vec![( value_parameters: vec![(
Identifier::new("x"), Identifier::new("x"),
TypeConstructor::Type(Type::Integer.with_position((7, 10))) TypeConstructor::Type(Type::Integer.with_position((7, 10)))
)], )],
return_type: TypeConstructor::Type(Type::Integer.with_position((12, 15))), return_type: TypeConstructor::Type(Type::Integer.with_position((15, 18))),
body: Block::new(vec![Statement::ValueExpression(Expression::Identifier( body: Block::new(vec![Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((18, 19)) Identifier::new("x").with_position((21, 22))
))]) ))])
.with_position((16, 21)), .with_position((19, 24)),
} }
.with_position((0, 21)) .with_position((0, 24))
),) ),)
) );
} }
#[test] #[test]
fn function_with_type_arguments() { fn function_with_type_arguments() {
assert_eq!( assert_eq!(
parse(&lex("fn (T, U)(x: T, y: U) T { x }").unwrap()).unwrap()[0], parse(&lex("fn T, U (x: T, y: U) -> T { x }").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::ParsedFunction { ValueNode::Parsed {
type_parameters: Some(vec![ type_parameters: Some(vec![Identifier::new("T"), Identifier::new("U"),]),
Identifier::new("T").with_position((4, 5)),
Identifier::new("U").with_position((7, 8)),
]),
value_parameters: vec![ value_parameters: vec![
( (
Identifier::new("x"), Identifier::new("x"),
TypeConstructor::Identifier( TypeConstructor::Identifier(
Identifier::new("T").with_position((13, 14)) Identifier::new("T").with_position((12, 13))
) )
), ),
( (
Identifier::new("y"), Identifier::new("y"),
TypeConstructor::Identifier( TypeConstructor::Identifier(
Identifier::new("U").with_position((19, 20)) Identifier::new("U").with_position((18, 19))
) )
) )
], ],
return_type: TypeConstructor::Identifier( return_type: TypeConstructor::Identifier(
Identifier::new("T").with_position((22, 23)) Identifier::new("T").with_position((24, 25))
), ),
body: Block::new(vec![Statement::ValueExpression(Expression::Identifier( body: Block::new(vec![Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((26, 27)) Identifier::new("x").with_position((28, 29))
))]) ))])
.with_position((24, 29)), .with_position((26, 31)),
} }
.with_position((0, 29)) .with_position((0, 31))
)) ))
) )
} }
@ -1042,7 +1083,7 @@ mod tests {
Statement::IfElse( Statement::IfElse(
IfElse::new( IfElse::new(
Expression::Value(ValueNode::Boolean(true).with_position((3, 7))), Expression::Value(ValueNode::Boolean(true).with_position((3, 7))),
Block::new(vec![Statement::ValueExpression(Expression::Value( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string()).with_position((10, 15)) ValueNode::String("foo".to_string()).with_position((10, 15))
))]) ))])
.with_position((8, 17)), .with_position((8, 17)),
@ -1061,13 +1102,13 @@ mod tests {
Statement::IfElse( Statement::IfElse(
IfElse::new( IfElse::new(
Expression::Value(ValueNode::Boolean(true).with_position((3, 7))), Expression::Value(ValueNode::Boolean(true).with_position((3, 7))),
Block::new(vec![Statement::ValueExpression(Expression::Value( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("foo".to_string()).with_position((9, 14)) ValueNode::String("foo".to_string()).with_position((9, 14))
))]) ))])
.with_position((8, 16)), .with_position((8, 16)),
Vec::with_capacity(0), Vec::with_capacity(0),
Some( Some(
Block::new(vec![Statement::ValueExpression(Expression::Value( Block::new(vec![Statement::Expression(Expression::Value(
ValueNode::String("bar".to_string()).with_position((24, 29)) ValueNode::String("bar".to_string()).with_position((24, 29))
))]) ))])
.with_position((22, 31)) .with_position((22, 31))
@ -1082,7 +1123,7 @@ mod tests {
fn map() { fn map() {
assert_eq!( assert_eq!(
parse(&lex("{ foo = 'bar' }").unwrap()).unwrap()[0], parse(&lex("{ foo = 'bar' }").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Map(vec![( ValueNode::Map(vec![(
Identifier::new("foo"), Identifier::new("foo"),
None, None,
@ -1093,7 +1134,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
parse(&lex("{ x = 1, y = 2, }").unwrap()).unwrap()[0], parse(&lex("{ x = 1, y = 2, }").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Map(vec![ ValueNode::Map(vec![
( (
Identifier::new("x"), Identifier::new("x"),
@ -1111,7 +1152,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
parse(&lex("{ x = 1 y = 2 }").unwrap()).unwrap()[0], parse(&lex("{ x = 1 y = 2 }").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Map(vec![ ValueNode::Map(vec![
( (
Identifier::new("x"), Identifier::new("x"),
@ -1133,7 +1174,7 @@ mod tests {
fn math() { fn math() {
assert_eq!( assert_eq!(
parse(&lex("1 + 1").unwrap()).unwrap()[0], parse(&lex("1 + 1").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Math( Statement::Expression(Expression::Math(
Box::new(Math::Add( Box::new(Math::Add(
Expression::Value(ValueNode::Integer(1).with_position((0, 1))), Expression::Value(ValueNode::Integer(1).with_position((0, 1))),
Expression::Value(ValueNode::Integer(1).with_position((4, 5))) Expression::Value(ValueNode::Integer(1).with_position((4, 5)))
@ -1148,7 +1189,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("loop { 42 }").unwrap()).unwrap()[0], parse(&lex("loop { 42 }").unwrap()).unwrap()[0],
Statement::Loop( Statement::Loop(
Loop::new(vec![Statement::ValueExpression(Expression::Value( Loop::new(vec![Statement::Expression(Expression::Value(
ValueNode::Integer(42).with_position((7, 9)) ValueNode::Integer(42).with_position((7, 9))
))]) ))])
.with_position((0, 11)) .with_position((0, 11))
@ -1177,7 +1218,7 @@ mod tests {
Identifier::new("i").with_position((33, 34)), Identifier::new("i").with_position((33, 34)),
None, None,
AssignmentOperator::AddAssign, AssignmentOperator::AddAssign,
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(1).with_position((38, 39)) ValueNode::Integer(1).with_position((38, 39))
)) ))
) )
@ -1198,7 +1239,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("{ x }").unwrap()).unwrap()[0], parse(&lex("{ x }").unwrap()).unwrap()[0],
Statement::Block( Statement::Block(
Block::new(vec![Statement::ValueExpression(Expression::Identifier( Block::new(vec![Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((2, 3)) Identifier::new("x").with_position((2, 3))
),)]) ),)])
.with_position((0, 5)) .with_position((0, 5))
@ -1219,13 +1260,13 @@ mod tests {
.unwrap()[0], .unwrap()[0],
Statement::Block( Statement::Block(
Block::new(vec![ Block::new(vec![
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((39, 40)) Identifier::new("x").with_position((39, 40))
)), )),
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("y").with_position((62, 63)) Identifier::new("y").with_position((62, 63))
)), )),
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("z").with_position((85, 86)) Identifier::new("z").with_position((85, 86))
)), )),
]) ])
@ -1246,14 +1287,14 @@ mod tests {
.unwrap()[0], .unwrap()[0],
Statement::Block( Statement::Block(
Block::new(vec![ Block::new(vec![
Statement::ValueExpression(Expression::Logic( Statement::Expression(Expression::Logic(
Box::new(Logic::Equal( Box::new(Logic::Equal(
Expression::Value(ValueNode::Integer(1).with_position((39, 40))), Expression::Value(ValueNode::Integer(1).with_position((39, 40))),
Expression::Value(ValueNode::Integer(1).with_position((44, 45))) Expression::Value(ValueNode::Integer(1).with_position((44, 45)))
)) ))
.with_position((39, 45)) .with_position((39, 45))
)), )),
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("z").with_position((66, 67)) Identifier::new("z").with_position((66, 67))
)), )),
]) ])
@ -1266,19 +1307,19 @@ mod tests {
fn identifier() { fn identifier() {
assert_eq!( assert_eq!(
parse(&lex("x").unwrap()).unwrap()[0], parse(&lex("x").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((0, 1)) Identifier::new("x").with_position((0, 1))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("foobar").unwrap()).unwrap()[0], parse(&lex("foobar").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("foobar").with_position((0, 6)) Identifier::new("foobar").with_position((0, 6))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("HELLO").unwrap()).unwrap()[0], parse(&lex("HELLO").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Identifier( Statement::Expression(Expression::Identifier(
Identifier::new("HELLO").with_position((0, 5)) Identifier::new("HELLO").with_position((0, 5))
)) ))
); );
@ -1293,7 +1334,7 @@ mod tests {
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
None, None,
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(1).with_position((9, 10)) ValueNode::Integer(1).with_position((9, 10))
)) ))
) )
@ -1311,7 +1352,7 @@ mod tests {
Identifier::new("foobar").with_position((0, 6)), Identifier::new("foobar").with_position((0, 6)),
Some(TypeConstructor::Type(Type::Integer.with_position((8, 11)))), Some(TypeConstructor::Type(Type::Integer.with_position((8, 11)))),
AssignmentOperator::Assign, AssignmentOperator::Assign,
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(1).with_position((14, 15)) ValueNode::Integer(1).with_position((14, 15))
)) ))
) )
@ -1324,7 +1365,7 @@ mod tests {
fn logic() { fn logic() {
assert_eq!( assert_eq!(
parse(&lex("x == 1").unwrap()).unwrap()[0], parse(&lex("x == 1").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Logic( Statement::Expression(Expression::Logic(
Box::new(Logic::Equal( Box::new(Logic::Equal(
Expression::Identifier(Identifier::new("x").with_position((0, 1))), Expression::Identifier(Identifier::new("x").with_position((0, 1))),
Expression::Value(ValueNode::Integer(1).with_position((5, 6))), Expression::Value(ValueNode::Integer(1).with_position((5, 6))),
@ -1335,7 +1376,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("(x == 1) && (y == 2)").unwrap()).unwrap()[0], parse(&lex("(x == 1) && (y == 2)").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Logic( Statement::Expression(Expression::Logic(
Box::new(Logic::And( Box::new(Logic::And(
Expression::Logic( Expression::Logic(
Box::new(Logic::Equal( Box::new(Logic::Equal(
@ -1358,7 +1399,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("(x == 1) && (y == 2) && true").unwrap()).unwrap()[0], parse(&lex("(x == 1) && (y == 2) && true").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Logic( Statement::Expression(Expression::Logic(
Box::new(Logic::And( Box::new(Logic::And(
Expression::Logic( Expression::Logic(
Box::new(Logic::And( Box::new(Logic::And(
@ -1396,13 +1437,13 @@ mod tests {
fn list() { fn list() {
assert_eq!( assert_eq!(
parse(&lex("[]").unwrap()).unwrap()[0], parse(&lex("[]").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::List(Vec::with_capacity(0)).with_position((0, 2)) ValueNode::List(Vec::with_capacity(0)).with_position((0, 2))
),) ),)
); );
assert_eq!( assert_eq!(
parse(&lex("[42]").unwrap()).unwrap()[0], parse(&lex("[42]").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::List(vec![Expression::Value( ValueNode::List(vec![Expression::Value(
ValueNode::Integer(42).with_position((1, 3)) ValueNode::Integer(42).with_position((1, 3))
)]) )])
@ -1411,7 +1452,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
parse(&lex("[42, 'foo', 'bar', [1, 2, 3,]]").unwrap()).unwrap()[0], parse(&lex("[42, 'foo', 'bar', [1, 2, 3,]]").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::List(vec![ ValueNode::List(vec![
Expression::Value(ValueNode::Integer(42).with_position((1, 3))), Expression::Value(ValueNode::Integer(42).with_position((1, 3))),
Expression::Value(ValueNode::String("foo".to_string()).with_position((5, 10))), Expression::Value(ValueNode::String("foo".to_string()).with_position((5, 10))),
@ -1434,7 +1475,7 @@ mod tests {
fn r#true() { fn r#true() {
assert_eq!( assert_eq!(
parse(&lex("true").unwrap()).unwrap()[0], parse(&lex("true").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Boolean(true).with_position((0, 4)) ValueNode::Boolean(true).with_position((0, 4))
)) ))
); );
@ -1444,7 +1485,7 @@ mod tests {
fn r#false() { fn r#false() {
assert_eq!( assert_eq!(
parse(&lex("false").unwrap()).unwrap()[0], parse(&lex("false").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Boolean(false).with_position((0, 5)) ValueNode::Boolean(false).with_position((0, 5))
)) ))
); );
@ -1454,13 +1495,13 @@ mod tests {
fn positive_float() { fn positive_float() {
assert_eq!( assert_eq!(
parse(&lex("0.0").unwrap()).unwrap()[0], parse(&lex("0.0").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(0.0).with_position((0, 3)) ValueNode::Float(0.0).with_position((0, 3))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("42.0").unwrap()).unwrap()[0], parse(&lex("42.0").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(42.0).with_position((0, 4)) ValueNode::Float(42.0).with_position((0, 4))
)) ))
); );
@ -1469,7 +1510,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex(&max_float).unwrap()).unwrap()[0], parse(&lex(&max_float).unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(f64::MAX).with_position((0, 311)) ValueNode::Float(f64::MAX).with_position((0, 311))
)) ))
); );
@ -1478,7 +1519,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex(&min_positive_float).unwrap()).unwrap()[0], parse(&lex(&min_positive_float).unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(f64::MIN_POSITIVE).with_position((0, 326)) ValueNode::Float(f64::MIN_POSITIVE).with_position((0, 326))
),) ),)
); );
@ -1488,13 +1529,13 @@ mod tests {
fn negative_float() { fn negative_float() {
assert_eq!( assert_eq!(
parse(&lex("-0.0").unwrap()).unwrap()[0], parse(&lex("-0.0").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(-0.0).with_position((0, 4)) ValueNode::Float(-0.0).with_position((0, 4))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("-42.0").unwrap()).unwrap()[0], parse(&lex("-42.0").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(-42.0).with_position((0, 5)) ValueNode::Float(-42.0).with_position((0, 5))
)) ))
); );
@ -1503,7 +1544,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex(&min_float).unwrap()).unwrap()[0], parse(&lex(&min_float).unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(f64::MIN).with_position((0, 312)) ValueNode::Float(f64::MIN).with_position((0, 312))
)) ))
); );
@ -1512,7 +1553,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex(&max_negative_float).unwrap()).unwrap()[0], parse(&lex(&max_negative_float).unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(-f64::MIN_POSITIVE).with_position((0, 327)) ValueNode::Float(-f64::MIN_POSITIVE).with_position((0, 327))
),) ),)
); );
@ -1522,18 +1563,18 @@ mod tests {
fn other_float() { fn other_float() {
assert_eq!( assert_eq!(
parse(&lex("Infinity").unwrap()).unwrap()[0], parse(&lex("Infinity").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(f64::INFINITY).with_position((0, 8)) ValueNode::Float(f64::INFINITY).with_position((0, 8))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("-Infinity").unwrap()).unwrap()[0], parse(&lex("-Infinity").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Float(f64::NEG_INFINITY).with_position((0, 9)) ValueNode::Float(f64::NEG_INFINITY).with_position((0, 9))
)) ))
); );
if let Statement::ValueExpression(Expression::Value(WithPosition { if let Statement::Expression(Expression::Value(WithPosition {
node: ValueNode::Float(float), node: ValueNode::Float(float),
.. ..
})) = &parse(&lex("NaN").unwrap()).unwrap()[0] })) = &parse(&lex("NaN").unwrap()).unwrap()[0]
@ -1553,7 +1594,7 @@ mod tests {
assert_eq!( assert_eq!(
statements[0], statements[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(i).with_position((0, 1)) ValueNode::Integer(i).with_position((0, 1))
)) ))
) )
@ -1561,7 +1602,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("42").unwrap()).unwrap()[0], parse(&lex("42").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(42).with_position((0, 2)) ValueNode::Integer(42).with_position((0, 2))
)) ))
); );
@ -1570,7 +1611,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex(&maximum_integer).unwrap()).unwrap()[0], parse(&lex(&maximum_integer).unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(i64::MAX).with_position((0, 19)) ValueNode::Integer(i64::MAX).with_position((0, 19))
)) ))
); );
@ -1585,7 +1626,7 @@ mod tests {
assert_eq!( assert_eq!(
statements[0], statements[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(i).with_position((0, 2)) ValueNode::Integer(i).with_position((0, 2))
)) ))
) )
@ -1593,7 +1634,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex("-42").unwrap()).unwrap()[0], parse(&lex("-42").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(-42).with_position((0, 3)) ValueNode::Integer(-42).with_position((0, 3))
)) ))
); );
@ -1602,7 +1643,7 @@ mod tests {
assert_eq!( assert_eq!(
parse(&lex(&minimum_integer).unwrap()).unwrap()[0], parse(&lex(&minimum_integer).unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::Integer(i64::MIN).with_position((0, 20)) ValueNode::Integer(i64::MIN).with_position((0, 20))
)) ))
); );
@ -1612,19 +1653,19 @@ mod tests {
fn double_quoted_string() { fn double_quoted_string() {
assert_eq!( assert_eq!(
parse(&lex("\"\"").unwrap()).unwrap()[0], parse(&lex("\"\"").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("".to_string()).with_position((0, 2)) ValueNode::String("".to_string()).with_position((0, 2))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("\"42\"").unwrap()).unwrap()[0], parse(&lex("\"42\"").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("42".to_string()).with_position((0, 4)) ValueNode::String("42".to_string()).with_position((0, 4))
),) ),)
); );
assert_eq!( assert_eq!(
parse(&lex("\"foobar\"").unwrap()).unwrap()[0], parse(&lex("\"foobar\"").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("foobar".to_string()).with_position((0, 8)) ValueNode::String("foobar".to_string()).with_position((0, 8))
),) ),)
); );
@ -1634,19 +1675,19 @@ mod tests {
fn single_quoted_string() { fn single_quoted_string() {
assert_eq!( assert_eq!(
parse(&lex("''").unwrap()).unwrap()[0], parse(&lex("''").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("".to_string()).with_position((0, 2)) ValueNode::String("".to_string()).with_position((0, 2))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("'42'").unwrap()).unwrap()[0], parse(&lex("'42'").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("42".to_string()).with_position((0, 4)) ValueNode::String("42".to_string()).with_position((0, 4))
),) ),)
); );
assert_eq!( assert_eq!(
parse(&lex("'foobar'").unwrap()).unwrap()[0], parse(&lex("'foobar'").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("foobar".to_string()).with_position((0, 8)) ValueNode::String("foobar".to_string()).with_position((0, 8))
),) ),)
); );
@ -1656,19 +1697,19 @@ mod tests {
fn grave_quoted_string() { fn grave_quoted_string() {
assert_eq!( assert_eq!(
parse(&lex("``").unwrap()).unwrap()[0], parse(&lex("``").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("".to_string()).with_position((0, 2)) ValueNode::String("".to_string()).with_position((0, 2))
)) ))
); );
assert_eq!( assert_eq!(
parse(&lex("`42`").unwrap()).unwrap()[0], parse(&lex("`42`").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("42".to_string()).with_position((0, 4)) ValueNode::String("42".to_string()).with_position((0, 4))
),) ),)
); );
assert_eq!( assert_eq!(
parse(&lex("`foobar`").unwrap()).unwrap()[0], parse(&lex("`foobar`").unwrap()).unwrap()[0],
Statement::ValueExpression(Expression::Value( Statement::Expression(Expression::Value(
ValueNode::String("foobar".to_string()).with_position((0, 8)) ValueNode::String("foobar".to_string()).with_position((0, 8))
),) ),)
); );

View File

@ -49,7 +49,7 @@ fn function_variable() {
Some(Vec::with_capacity(0)), Some(Vec::with_capacity(0)),
vec![(Identifier::new("x"), Type::Integer)], vec![(Identifier::new("x"), Type::Integer)],
Type::Integer, Type::Integer,
Block::new(vec![Statement::ValueExpression(Expression::Identifier( Block::new(vec![Statement::Expression(Expression::Identifier(
Identifier::new("x").with_position((27, 28)) Identifier::new("x").with_position((27, 28))
))]) ))])
))) )))

View File

@ -59,7 +59,9 @@ fn main() {
let context = Context::new(None); let context = Context::new(None);
let mut interpreter = Interpreter::new(context.clone()); let mut interpreter = Interpreter::new(context.clone());
if !args.no_std {
interpreter.load_std().unwrap(); interpreter.load_std().unwrap();
}
let (source_id, source): (Arc<str>, Arc<str>) = if let Some(path) = args.path { let (source_id, source): (Arc<str>, Arc<str>) = if let Some(path) = args.path {
let source = read_to_string(&path).unwrap(); let source = read_to_string(&path).unwrap();

View File

@ -1,3 +1,3 @@
length = fn (input: list) int { length = fn (input: [any]) -> int {
LENGTH input LENGTH input
} }

View File

@ -1,5 +1,5 @@
fs = { fs = {
read_file = fn (path: str) str { read_file = fn (path: str) -> str {
READ_FILE path READ_FILE path
} }
} }

View File

@ -1,9 +1,9 @@
io = { io = {
read_line = fn () str { read_line = fn () -> str {
READ_LINE READ_LINE
} }
write_line = fn (output: any) none { write_line = fn (output: any) -> none {
WRITE_LINE output WRITE_LINE output
} }
} }

View File

@ -1,5 +1,5 @@
json = { json = {
parse = fn (T)(input: str) T { parse = fn (T)(input: str) -> T {
JSON_PARSE T input JSON_PARSE T input
} }
} }

View File

@ -1,5 +1,5 @@
thread = { thread = {
sleep = fn (milliseconds: int) none { sleep = fn (milliseconds: int) -> none {
SLEEP milliseconds SLEEP milliseconds
} }
} }