mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-01-07 05:59:03 +01:00
Prepared for supporting multiple function arguments. The types now support several arguments, and the only thing left is to parse this.
This commit is contained in:
parent
94722ed27e
commit
6d67797565
@ -75,11 +75,16 @@ impl Visitor<f64, f64> for Interpreter {
|
||||
self.symbol_table.insert(identifier.clone(), stmt.clone());
|
||||
0f64
|
||||
}
|
||||
Stmt::FnDecl(identifier, argument, _) => {
|
||||
self.visit_stmt(&Stmt::VarDecl(
|
||||
argument.clone(),
|
||||
Box::new(Expr::Literal(String::from("0"))),
|
||||
));
|
||||
Stmt::FnDecl(identifier, arguments, _) => {
|
||||
// Initialise each of the arguments as their own variable.
|
||||
for argument in arguments {
|
||||
self.visit_stmt(&Stmt::VarDecl(
|
||||
argument.clone(),
|
||||
Box::new(Expr::Literal(String::from("0"))),
|
||||
));
|
||||
}
|
||||
|
||||
// Add the function to the symbol table.
|
||||
self.symbol_table
|
||||
.insert(format!("{}()", identifier.clone()), stmt.clone());
|
||||
0f64
|
||||
@ -134,9 +139,16 @@ impl Visitor<f64, f64> for Interpreter {
|
||||
}
|
||||
Expr::Literal(value) => value.parse().unwrap(),
|
||||
Expr::Group(expr) => self.visit_expr(&expr),
|
||||
Expr::FnCall(identifier, expr) => {
|
||||
let x = self.visit_expr(&expr);
|
||||
if let Some(result) = self.prelude.call_unary_func(identifier, x) {
|
||||
Expr::FnCall(identifier, expressions) => {
|
||||
let prelude_func = match expressions.len() {
|
||||
1 => {
|
||||
let x = self.visit_expr(&expressions[0]);
|
||||
self.prelude.call_unary_func(identifier, x)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(result) = prelude_func {
|
||||
result
|
||||
} else {
|
||||
let stmt = self
|
||||
@ -144,13 +156,24 @@ impl Visitor<f64, f64> for Interpreter {
|
||||
.get(&format!("{}()", identifier))
|
||||
.expect("Undefined function")
|
||||
.clone();
|
||||
match stmt {
|
||||
Stmt::FnDecl(_, argument, fn_body) => {
|
||||
self.visit_stmt(&Stmt::VarDecl(argument.clone(), expr.clone()));
|
||||
self.visit_expr(&*fn_body)
|
||||
|
||||
if let Stmt::FnDecl(_, arguments, fn_body) = stmt {
|
||||
if arguments.len() != expressions.len() {
|
||||
panic!("Incorrect amount of arguments.");
|
||||
}
|
||||
_ => panic!(),
|
||||
|
||||
// Initialise the arguments as their own variables.
|
||||
for (i, argument) in arguments.iter().enumerate() {
|
||||
self.visit_stmt(&Stmt::VarDecl(
|
||||
argument.clone(),
|
||||
Box::new(expressions[i].clone()),
|
||||
));
|
||||
}
|
||||
|
||||
return self.visit_expr(&*fn_body);
|
||||
}
|
||||
|
||||
panic!("Unexpected error.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,22 @@ pub enum TokenKind {
|
||||
Unknown,
|
||||
Literal,
|
||||
Identifier,
|
||||
|
||||
Plus,
|
||||
Minus,
|
||||
Star,
|
||||
Slash,
|
||||
Power,
|
||||
Equals,
|
||||
|
||||
Deg,
|
||||
Rad,
|
||||
|
||||
Pipe,
|
||||
OpenParenthesis,
|
||||
ClosedParenthesis,
|
||||
Comma,
|
||||
|
||||
EOF,
|
||||
}
|
||||
|
||||
@ -101,6 +106,10 @@ impl<'a> Lexer<'a> {
|
||||
self.advance();
|
||||
self.build(TokenKind::Equals, "")
|
||||
}
|
||||
',' => {
|
||||
self.advance();
|
||||
self.build(TokenKind::Comma, "")
|
||||
}
|
||||
_ => {
|
||||
if c.is_digit(10) {
|
||||
self.next_number_literal()
|
||||
|
@ -5,7 +5,7 @@ use crate::lexer::{Token, TokenKind};
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Stmt {
|
||||
VarDecl(String, Box<Expr>),
|
||||
FnDecl(String, String, Box<Expr>),
|
||||
FnDecl(String, Vec<String>, Box<Expr>),
|
||||
Expr(Box<Expr>),
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ pub enum Expr {
|
||||
Unit(Box<Expr>, TokenKind),
|
||||
Var(String),
|
||||
Group(Box<Expr>),
|
||||
FnCall(String, Box<Expr>),
|
||||
FnCall(String, Vec<Expr>),
|
||||
Literal(String),
|
||||
}
|
||||
|
||||
@ -85,15 +85,23 @@ impl Parser {
|
||||
self.advance();
|
||||
let expr = self.parse_expr();
|
||||
|
||||
match primary {
|
||||
Expr::FnCall(identifier, argument) => match *argument {
|
||||
Expr::Var(argument_identifier) => {
|
||||
Stmt::FnDecl(identifier, argument_identifier, Box::new(expr))
|
||||
// Use the "function call" expression that was parsed, and put its values into a function declaration statement instead.
|
||||
if let Expr::FnCall(identifier, parameters) = primary {
|
||||
let mut parameter_identifiers = Vec::new();
|
||||
|
||||
// All the "arguments" are expected to be parsed as variables,
|
||||
// since parameter definitions look the same as variable references.
|
||||
// Extract these.
|
||||
for parameter in parameters {
|
||||
if let Expr::Var(parameter_identifier) = parameter {
|
||||
parameter_identifiers.push(parameter_identifier);
|
||||
}
|
||||
_ => panic!("Unexpected error."),
|
||||
},
|
||||
_ => panic!("Unexpected error."),
|
||||
}
|
||||
|
||||
return Stmt::FnDecl(identifier, parameter_identifiers, Box::new(expr));
|
||||
}
|
||||
|
||||
panic!("Unexpected error.");
|
||||
} else {
|
||||
// It is a function call, not a function declaration.
|
||||
// Redo the parsing for this specific part.
|
||||
@ -199,7 +207,7 @@ impl Parser {
|
||||
let group_expr = Expr::Group(Box::new(self.parse_expr()));
|
||||
self.consume(TokenKind::Pipe);
|
||||
|
||||
Expr::FnCall(String::from("abs"), Box::new(group_expr))
|
||||
Expr::FnCall(String::from("abs"), vec![group_expr])
|
||||
}
|
||||
|
||||
fn parse_identifier(&mut self) -> Expr {
|
||||
@ -210,7 +218,7 @@ impl Parser {
|
||||
let parameter = self.parse_expr();
|
||||
self.consume(TokenKind::ClosedParenthesis);
|
||||
|
||||
Expr::FnCall(identifier.value, Box::new(parameter))
|
||||
Expr::FnCall(identifier.value, vec![parameter])
|
||||
} else {
|
||||
Expr::Var(identifier.value)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user