Skip to content

Commit

Permalink
feat: runtime setup
Browse files Browse the repository at this point in the history
  • Loading branch information
viddrobnic committed May 31, 2024
1 parent ca1d132 commit b047618
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 57 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["parser"]
members = ["parser", "runtime"]

[package]
name = "aoc-lang"
Expand Down
35 changes: 24 additions & 11 deletions parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,20 @@ pub enum NodeValue {
If(IfNode),
While {
condition: Box<Node>,
body: Vec<Node>,
body: Block,
},
For {
initial: Box<Node>,
condition: Box<Node>,
after: Box<Node>,
body: Vec<Node>,
body: Block,
},
Break,
Continue,
FunctionLiteral {
name: Option<String>,
parameters: Vec<String>,
body: Vec<Node>,
body: Block,
},
FunctionCall {
function: Box<Node>,
Expand All @@ -81,8 +81,14 @@ pub struct HashLiteralPair {
#[derive(Debug, PartialEq, Clone)]
pub struct IfNode {
pub condition: Box<Node>,
pub consequence: Vec<Node>,
pub alternative: Vec<Node>,
pub consequence: Block,
pub alternative: Option<Block>,
}

#[derive(Debug, PartialEq, Clone)]
pub struct Block {
pub nodes: Vec<Node>,
pub range: Range,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
Expand Down Expand Up @@ -228,17 +234,21 @@ impl Display for NodeValue {
NodeValue::If(if_node) => {
let cons = if_node
.consequence
.nodes
.iter()
.map(|node| node.to_string())
.collect::<Vec<_>>()
.join("\n");

let alt = if_node
.alternative
.iter()
.map(|node| node.to_string())
.collect::<Vec<_>>()
.join("\n");
let mut alt = String::new();
if let Some(alternative) = &if_node.alternative {
alt = alternative
.nodes
.iter()
.map(|node| node.to_string())
.collect::<Vec<_>>()
.join("\n");
}

write!(
f,
Expand All @@ -248,6 +258,7 @@ impl Display for NodeValue {
}
NodeValue::While { condition, body } => {
let body = body
.nodes
.iter()
.map(|node| node.to_string())
.collect::<Vec<_>>()
Expand All @@ -262,6 +273,7 @@ impl Display for NodeValue {
body,
} => {
let body = body
.nodes
.iter()
.map(|node| node.to_string())
.collect::<Vec<_>>()
Expand All @@ -277,6 +289,7 @@ impl Display for NodeValue {
body,
} => {
let body = body
.nodes
.iter()
.map(|node| node.to_string())
.collect::<Vec<_>>()
Expand Down
4 changes: 3 additions & 1 deletion parser/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
pub mod ast;
pub mod error;
pub mod parser;
pub mod position;

mod lexer;
mod parser;
mod token;

pub use parser::parse;
42 changes: 29 additions & 13 deletions parser/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ impl Parser<'_> {
let mut if_node = ast::IfNode {
condition: Box::new(condition),
consequence,
alternative: vec![],
alternative: None,
};

// After consequence we can have eof, eol or else.
Expand All @@ -466,18 +466,22 @@ impl Parser<'_> {
if token.kind == TokenKind::If {
let (alternative, alternative_end) = self.parse_if()?;

if_node.alternative = vec![ast::Node {
value: ast::NodeValue::If(alternative),
range: Range {
start: token.range.start,
end: alternative_end,
},
}];
let range = Range {
start: token.range.start,
end: alternative_end,
};
if_node.alternative = Some(ast::Block {
nodes: vec![ast::Node {
value: ast::NodeValue::If(alternative),
range,
}],
range,
});
Ok((if_node, alternative_end))
} else {
let (alternative, alternative_end) = self.parse_block(token)?;

if_node.alternative = alternative;
if_node.alternative = Some(alternative);
Ok((if_node, alternative_end))
}
}
Expand Down Expand Up @@ -606,13 +610,25 @@ impl Parser<'_> {
// position of `}`
//
// This function checks if the start token is `{`, so the caller doesn't have to do this.
fn parse_block(&mut self, start_token: Token) -> Result<(Vec<ast::Node>, Position)> {
fn parse_block(&mut self, start_token: Token) -> Result<(ast::Block, Position)> {
// Start token should be `{`
validate_token_kind(&start_token, TokenKind::LCurly)?;

self.parse_multiple(TokenKind::RCurly, TokenKind::Eol, |parser, token| {
parser.parse_node(token, Precedence::Lowest)
})
let (nodes, end) =
self.parse_multiple(TokenKind::RCurly, TokenKind::Eol, |parser, token| {
parser.parse_node(token, Precedence::Lowest)
})?;

Ok((
ast::Block {
nodes,
range: Range {
start: start_token.range.start,
end,
},
},
end,
))
}

// Helper function used for parsing arrays, hash maps, function arguments, function calls.
Expand Down
Loading

0 comments on commit b047618

Please sign in to comment.