Skip to content

Commit

Permalink
feat: add range info to ast func params
Browse files Browse the repository at this point in the history
  • Loading branch information
viddrobnic committed Jul 28, 2024
1 parent 9217d8b commit fe85bd2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 11 deletions.
16 changes: 14 additions & 2 deletions parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,16 @@ pub struct For {
pub body: Block,
}

#[derive(Debug, PartialEq, Clone)]
pub struct FunctionParamter {
pub name: String,
pub range: Range,
}

#[derive(Debug, PartialEq, Clone)]
pub struct FunctionLiteral {
pub name: Option<String>,
pub parameters: Vec<String>,
pub parameters: Vec<FunctionParamter>,
pub body: Block,
}

Expand Down Expand Up @@ -324,7 +330,13 @@ impl Display for NodeValue {
.collect::<Vec<_>>()
.join("\n");

write!(f, "fn({}) {{{}}}", parameters.join(", "), body)
let parameters = parameters
.iter()
.map(|par| par.name.clone())
.collect::<Vec<_>>()
.join(", ");

write!(f, "fn({}) {{{}}}", parameters, body)
}
NodeValue::FunctionCall(FunctionCall {
function,
Expand Down
10 changes: 6 additions & 4 deletions parser/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::{
ast::{self, InfixOperatorKind, NodeKind, PrefixOperatorKind},
ast::{self, FunctionParamter, InfixOperatorKind, NodeKind, PrefixOperatorKind},
error::{Error, ErrorKind, Result},
lexer::Lexer,
parser::precedence::Precedence,
parser::validate::*,
parser::{precedence::Precedence, validate::*},
position::{Position, Range},
token::{Token, TokenKind},
};
Expand Down Expand Up @@ -569,7 +568,10 @@ impl Parser<'_> {
TokenKind::RBracket,
TokenKind::Comma,
|_, token| match token.kind {
TokenKind::Ident(ident) => Ok(ident),
TokenKind::Ident(ident) => Ok(FunctionParamter {
name: ident,
range: token.range,
}),
_ => Err(Error {
kind: ErrorKind::InvalidFunctionParameter,
range: token.range,
Expand Down
26 changes: 24 additions & 2 deletions parser/src/parser/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,13 @@ fn fn_literal() -> Result<()> {
ast::Node {
value: ast::NodeValue::FunctionLiteral(ast::FunctionLiteral {
name: None,
parameters: vec!["a".to_string()],
parameters: vec![ast::FunctionParamter {
name: "a".to_string(),
range: Range {
start: Position::new(0, 3),
end: Position::new(0, 4),
},
}],
body: ast::Block {
nodes: vec![],
range: Range {
Expand All @@ -1155,7 +1161,23 @@ fn fn_literal() -> Result<()> {
ast::Node {
value: ast::NodeValue::FunctionLiteral(ast::FunctionLiteral {
name: None,
parameters: vec!["a".to_string(), "b".to_string()],
// parameters: vec!["a".to_string(), "b".to_string()],
parameters: vec![
ast::FunctionParamter {
name: "a".to_string(),
range: Range {
start: Position::new(0, 3),
end: Position::new(0, 4),
},
},
ast::FunctionParamter {
name: "b".to_string(),
range: Range {
start: Position::new(0, 6),
end: Position::new(0, 7),
},
},
],
body: ast::Block {
nodes: vec![],
range: Range {
Expand Down
27 changes: 27 additions & 0 deletions parser/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ impl Position {
pub fn new(line: usize, character: usize) -> Self {
Self { line, character }
}

pub fn cmp_range(&self, range: &Range) -> PositionOrdering {
if self.line < range.start.line {
return PositionOrdering::Before;
}

if self.line == range.start.line && self.character < range.start.character {
return PositionOrdering::Before;
}

if self.line > range.end.line {
return PositionOrdering::After;
}

if self.line == range.end.line && self.character >= range.end.character {
return PositionOrdering::After;
}

PositionOrdering::Inside
}
}

#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
Expand All @@ -29,3 +49,10 @@ impl Range {
Self { start, end }
}
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum PositionOrdering {
Before,
Inside,
After,
}
2 changes: 1 addition & 1 deletion runtime/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ impl Compiler {

// Define argument symbols
for param in &fn_literal.parameters {
self.symbol_table.define(param.to_string());
self.symbol_table.define(param.name.to_string());
}

// Compile body
Expand Down
5 changes: 3 additions & 2 deletions runtime/src/compiler/symbol_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl SymbolTable {
let symbol = self.resolve_at(idx - 1, name);
match symbol {
None => None,
Some(Symbol::Global(_)) => symbol,
Some(Symbol::Global(_)) | Some(Symbol::Builtin(_)) => symbol,
Some(sym) => Some(self.define_free(idx, sym, name)),
}
}
Expand All @@ -120,7 +120,7 @@ impl SymbolTable {

#[cfg(test)]
mod test {
use crate::compiler::symbol_table::Symbol;
use crate::{builtin::Builtin, compiler::symbol_table::Symbol};

use super::SymbolTable;

Expand Down Expand Up @@ -160,6 +160,7 @@ mod test {
table.enter_scope();

assert_eq!(table.resolve("a"), Some(Symbol::Global(0)));
assert_eq!(table.resolve("len"), Some(Symbol::Builtin(Builtin::Len)));

table.define("b".to_string());
assert_eq!(table.resolve("b"), Some(Symbol::Local(0)));
Expand Down

0 comments on commit fe85bd2

Please sign in to comment.