From d53ddd07ebd053c7018e61b21dcf9b18f2382785 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 17 Jun 2024 15:47:07 -0400 Subject: [PATCH] Fix tests and refine new parsing --- dust-lang/src/abstract_tree/block.rs | 10 +- dust-lang/src/abstract_tree/if_else.rs | 2 +- dust-lang/src/abstract_tree/statement.rs | 10 +- .../src/abstract_tree/type_constructor.rs | 8 +- dust-lang/src/abstract_tree/value_node.rs | 20 +- dust-lang/src/parser.rs | 353 ++++++++++-------- dust-lang/tests/variables.rs | 2 +- dust-shell/src/main.rs | 4 +- std/core.ds | 2 +- std/fs.ds | 2 +- std/io.ds | 4 +- std/json.ds | 2 +- std/thread.ds | 2 +- 13 files changed, 234 insertions(+), 187 deletions(-) diff --git a/dust-lang/src/abstract_tree/block.rs b/dust-lang/src/abstract_tree/block.rs index 91dc89d..e9d4d72 100644 --- a/dust-lang/src/abstract_tree/block.rs +++ b/dust-lang/src/abstract_tree/block.rs @@ -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)), )), ]); diff --git a/dust-lang/src/abstract_tree/if_else.rs b/dust-lang/src/abstract_tree/if_else.rs index 33461f5..5ae8640 100644 --- a/dust-lang/src/abstract_tree/if_else.rs +++ b/dust-lang/src/abstract_tree/if_else.rs @@ -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)), diff --git a/dust-lang/src/abstract_tree/statement.rs b/dust-lang/src/abstract_tree/statement.rs index b7c50b7..31c3854 100644 --- a/dust-lang/src/abstract_tree/statement.rs +++ b/dust-lang/src/abstract_tree/statement.rs @@ -20,7 +20,7 @@ pub enum Statement { Loop(WithPosition), StructureDefinition(WithPosition), TypeAssignment(WithPosition), - ValueExpression(Expression), + Expression(Expression), While(WithPosition), } @@ -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 { 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), diff --git a/dust-lang/src/abstract_tree/type_constructor.rs b/dust-lang/src/abstract_tree/type_constructor.rs index 7a8744b..630e691 100644 --- a/dust-lang/src/abstract_tree/type_constructor.rs +++ b/dust-lang/src/abstract_tree/type_constructor.rs @@ -18,7 +18,7 @@ pub enum TypeConstructor { #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct FunctionTypeConstructor { pub type_parameters: Option>>, - pub value_parameters: Vec<(WithPosition, Box)>, + pub value_parameters: Vec, pub return_type: Box, } @@ -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!(), } } } diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index d64123b..328af35 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -26,8 +26,8 @@ pub enum ValueNode { name: WithPosition, fields: Vec<(WithPosition, Expression)>, }, - ParsedFunction { - type_parameters: Option>>, + Parsed { + type_parameters: Option>, value_parameters: Vec<(Identifier, TypeConstructor)>, return_type: TypeConstructor, body: WithPosition, @@ -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)?; diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 42973d7..aa2ef55 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -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)) ),) ); diff --git a/dust-lang/tests/variables.rs b/dust-lang/tests/variables.rs index d108d34..f663d4a 100644 --- a/dust-lang/tests/variables.rs +++ b/dust-lang/tests/variables.rs @@ -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)) ))]) ))) diff --git a/dust-shell/src/main.rs b/dust-shell/src/main.rs index ad3b548..eabeb84 100644 --- a/dust-shell/src/main.rs +++ b/dust-shell/src/main.rs @@ -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, Arc) = if let Some(path) = args.path { let source = read_to_string(&path).unwrap(); diff --git a/std/core.ds b/std/core.ds index e57fd24..a9a0c92 100644 --- a/std/core.ds +++ b/std/core.ds @@ -1,3 +1,3 @@ -length = fn (input: list) int { +length = fn (input: [any]) -> int { LENGTH input } diff --git a/std/fs.ds b/std/fs.ds index e170502..7e92ad3 100644 --- a/std/fs.ds +++ b/std/fs.ds @@ -1,5 +1,5 @@ fs = { - read_file = fn (path: str) str { + read_file = fn (path: str) -> str { READ_FILE path } } diff --git a/std/io.ds b/std/io.ds index 63bcb25..02a5df2 100644 --- a/std/io.ds +++ b/std/io.ds @@ -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 } } diff --git a/std/json.ds b/std/json.ds index 47cd9e7..477bfba 100644 --- a/std/json.ds +++ b/std/json.ds @@ -1,5 +1,5 @@ json = { - parse = fn (T)(input: str) T { + parse = fn (T)(input: str) -> T { JSON_PARSE T input } } diff --git a/std/thread.ds b/std/thread.ds index 08f9a0a..bd2f78b 100644 --- a/std/thread.ds +++ b/std/thread.ds @@ -1,5 +1,5 @@ thread = { - sleep = fn (milliseconds: int) none { + sleep = fn (milliseconds: int) -> none { SLEEP milliseconds } }