Fix lexing and parsing errors
This commit is contained in:
parent
9c77ae2410
commit
aadb51e1f1
@ -15,6 +15,10 @@ impl Block {
|
||||
Self { statements }
|
||||
}
|
||||
|
||||
pub fn first_statement(&self) -> &Statement {
|
||||
self.statements.first().unwrap()
|
||||
}
|
||||
|
||||
pub fn last_statement(&self) -> &Statement {
|
||||
self.statements.last().unwrap()
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ impl AbstractNode for IfElse {
|
||||
.check(&actual)
|
||||
.map_err(|conflict| ValidationError::TypeCheck {
|
||||
conflict,
|
||||
actual_position: self.if_block.item.last_statement().position(),
|
||||
expected_position: self.if_expression.position(),
|
||||
actual_position: else_block.item.last_statement().position(),
|
||||
expected_position: self.if_block.item.first_statement().position(),
|
||||
})?;
|
||||
}
|
||||
} else {
|
||||
@ -89,9 +89,9 @@ impl AbstractNode for IfElse {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(self, context: &mut Context, _clear_variables: bool) -> Result<Action, RuntimeError> {
|
||||
fn run(self, context: &mut Context, _manage_memory: bool) -> Result<Action, RuntimeError> {
|
||||
let if_position = self.if_expression.position();
|
||||
let action = self.if_expression.run(context, _clear_variables)?;
|
||||
let action = self.if_expression.run(context, _manage_memory)?;
|
||||
let value = if let Action::Return(value) = action {
|
||||
value
|
||||
} else {
|
||||
@ -102,11 +102,11 @@ impl AbstractNode for IfElse {
|
||||
|
||||
if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() {
|
||||
if *if_boolean {
|
||||
self.if_block.item.run(context, _clear_variables)
|
||||
self.if_block.item.run(context, _manage_memory)
|
||||
} else {
|
||||
for (expression, block) in self.else_ifs {
|
||||
let expression_position = expression.position();
|
||||
let action = expression.run(context, _clear_variables)?;
|
||||
let action = expression.run(context, _manage_memory)?;
|
||||
let value = if let Action::Return(value) = action {
|
||||
value
|
||||
} else {
|
||||
@ -117,7 +117,7 @@ impl AbstractNode for IfElse {
|
||||
|
||||
if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() {
|
||||
if *else_if_boolean {
|
||||
return block.item.run(context, _clear_variables);
|
||||
return block.item.run(context, _manage_memory);
|
||||
}
|
||||
} else {
|
||||
return Err(RuntimeError::ValidationFailure(
|
||||
@ -130,7 +130,7 @@ impl AbstractNode for IfElse {
|
||||
}
|
||||
|
||||
if let Some(else_statement) = self.else_block {
|
||||
else_statement.item.run(context, _clear_variables)
|
||||
else_statement.item.run(context, _manage_memory)
|
||||
} else {
|
||||
Ok(Action::None)
|
||||
}
|
||||
|
@ -32,10 +32,10 @@ impl AbstractNode for While {
|
||||
_context: &mut Context,
|
||||
_manage_memory: bool,
|
||||
) -> Result<(), ValidationError> {
|
||||
self.expression.validate(_context, _manage_memory)?;
|
||||
self.expression.validate(_context, false)?;
|
||||
|
||||
for statement in &self.statements {
|
||||
statement.validate(_context, _manage_memory)?;
|
||||
statement.validate(_context, false)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -44,10 +44,7 @@ impl AbstractNode for While {
|
||||
fn run(self, _context: &mut Context, _manage_memory: bool) -> Result<Action, RuntimeError> {
|
||||
let get_boolean = || -> Result<Value, RuntimeError> {
|
||||
let expression_position = self.expression.position();
|
||||
let action = self
|
||||
.expression
|
||||
.clone()
|
||||
.run(&mut _context.clone(), _manage_memory)?;
|
||||
let action = self.expression.clone().run(&mut _context.clone(), false)?;
|
||||
|
||||
if let Action::Return(value) = action {
|
||||
Ok(value)
|
||||
@ -60,9 +57,7 @@ impl AbstractNode for While {
|
||||
|
||||
while let ValueInner::Boolean(true) = get_boolean()?.inner().as_ref() {
|
||||
for statement in &self.statements {
|
||||
let action = statement
|
||||
.clone()
|
||||
.run(&mut _context.clone(), _manage_memory)?;
|
||||
let action = statement.clone().run(&mut _context.clone(), false)?;
|
||||
|
||||
match action {
|
||||
Action::Return(_) => {}
|
||||
|
@ -254,7 +254,30 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
delimited_string('`'),
|
||||
));
|
||||
|
||||
let identifier = text::ident().map(|text: &str| Token::Identifier(text));
|
||||
let identifier_and_keyword = text::ident().map(|text: &str| match text {
|
||||
"any" => Token::Keyword(Keyword::Any),
|
||||
"async" => Token::Keyword(Keyword::Async),
|
||||
"bool" => Token::Keyword(Keyword::Bool),
|
||||
"break" => Token::Keyword(Keyword::Break),
|
||||
"else" => Token::Keyword(Keyword::Else),
|
||||
"float" => Token::Keyword(Keyword::Float),
|
||||
"fn" => Token::Keyword(Keyword::Fn),
|
||||
"int" => Token::Keyword(Keyword::Int),
|
||||
"if" => Token::Keyword(Keyword::If),
|
||||
"list" => Token::Keyword(Keyword::List),
|
||||
"map" => Token::Keyword(Keyword::Map),
|
||||
"none" => Token::Keyword(Keyword::None),
|
||||
"range" => Token::Keyword(Keyword::Range),
|
||||
"struct" => Token::Keyword(Keyword::Struct),
|
||||
"str" => Token::Keyword(Keyword::Str),
|
||||
"type" => Token::Keyword(Keyword::Type),
|
||||
"loop" => Token::Keyword(Keyword::Loop),
|
||||
"while" => Token::Keyword(Keyword::While),
|
||||
"READ_LINE" => Token::Keyword(Keyword::ReadLine),
|
||||
"SLEEP" => Token::Keyword(Keyword::Sleep),
|
||||
"WRITE_LINE" => Token::Keyword(Keyword::WriteLine),
|
||||
_ => Token::Identifier(text),
|
||||
});
|
||||
|
||||
let operator = choice((
|
||||
// logic
|
||||
@ -302,31 +325,6 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
))
|
||||
.map(Token::Control);
|
||||
|
||||
let keyword = choice((
|
||||
just("any").to(Keyword::Any),
|
||||
just("async").to(Keyword::Async),
|
||||
just("bool").to(Keyword::Bool),
|
||||
just("break").to(Keyword::Break),
|
||||
just("else").to(Keyword::Else),
|
||||
just("float").to(Keyword::Float),
|
||||
just("fn").to(Keyword::Fn),
|
||||
just("int").to(Keyword::Int),
|
||||
just("if").to(Keyword::If),
|
||||
just("list").to(Keyword::List),
|
||||
just("map").to(Keyword::Map),
|
||||
just("none").to(Keyword::None),
|
||||
just("range").to(Keyword::Range),
|
||||
just("struct").to(Keyword::Struct),
|
||||
just("str").to(Keyword::Str),
|
||||
just("type").to(Keyword::Type),
|
||||
just("loop").to(Keyword::Loop),
|
||||
just("while").to(Keyword::While),
|
||||
just("READ_LINE").to(Keyword::ReadLine),
|
||||
just("SLEEP").to(Keyword::Sleep),
|
||||
just("WRITE_LINE").to(Keyword::WriteLine),
|
||||
))
|
||||
.map(Token::Keyword);
|
||||
|
||||
choice((
|
||||
line_comment,
|
||||
multi_line_comment,
|
||||
@ -334,8 +332,7 @@ pub fn lexer<'src>() -> impl Parser<
|
||||
float,
|
||||
integer,
|
||||
string,
|
||||
keyword,
|
||||
identifier,
|
||||
identifier_and_keyword,
|
||||
control,
|
||||
operator,
|
||||
))
|
||||
|
@ -4,15 +4,17 @@ while count <= 15 {
|
||||
divides_by_3 = count % 3 == 0
|
||||
divides_by_5 = count % 5 == 0
|
||||
|
||||
if divides_by_3 && divides_by_5 {
|
||||
io.write_line('fizzbuzz')
|
||||
output = if divides_by_3 && divides_by_5 {
|
||||
'fizzbuzz'
|
||||
} else if divides_by_3 {
|
||||
io.write_line('fizz')
|
||||
'fizz'
|
||||
} else if divides_by_5 {
|
||||
io.write_line('buzz')
|
||||
} else {
|
||||
io.write_line(count)
|
||||
'buzz'
|
||||
} else {
|
||||
string.new(count)
|
||||
}
|
||||
|
||||
io.write_line(output)
|
||||
|
||||
count += 1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user