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

View File

@ -168,7 +168,7 @@ mod tests {
assert_eq!(
IfElse::new(
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))
))])
.with_position((0, 0)),

View File

@ -20,7 +20,7 @@ pub enum Statement {
Loop(WithPosition<Loop>),
StructureDefinition(WithPosition<StructureDefinition>),
TypeAssignment(WithPosition<TypeAssignment>),
ValueExpression(Expression),
Expression(Expression),
While(WithPosition<While>),
}
@ -31,7 +31,7 @@ impl Statement {
Statement::AsyncBlock(inner) => inner.position,
Statement::Block(inner) => inner.position,
Statement::Break(inner) => inner.position,
Statement::ValueExpression(expression) => expression.position(),
Statement::Expression(expression) => expression.position(),
Statement::IfElse(inner) => inner.position,
Statement::Loop(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::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::Loop(r#loop) => r#loop.node.validate(_context, _manage_memory),
Statement::StructureDefinition(structure_definition) => {
@ -77,7 +77,7 @@ impl AbstractNode for Statement {
Statement::AsyncBlock(async_block) => async_block.node.evaluate(context, manage_memory),
Statement::Block(block) => block.node.evaluate(context, manage_memory),
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::Loop(r#loop) => r#loop.node.evaluate(context, manage_memory),
Statement::StructureDefinition(structure_definition) => {
@ -100,7 +100,7 @@ impl AbstractNode for Statement {
impl ExpectedType for Statement {
fn expected_type(&self, _context: &mut Context) -> Result<Type, ValidationError> {
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::Block(block) => 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)]
pub struct FunctionTypeConstructor {
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>,
}
@ -72,8 +72,12 @@ impl TypeConstructor {
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::ListOf(_) => todo!(),
}
}
}

View File

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

View File

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

View File

@ -49,7 +49,7 @@ fn function_variable() {
Some(Vec::with_capacity(0)),
vec![(Identifier::new("x"), 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))
))])
)))

View File

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

View File

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

View File

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

View File

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

View File

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