Skip to content

Commit 34a3b1a

Browse files
committed
[fix] Function arguments are only a vector of FormalArgument, instead of an Option.
1 parent b51c8b6 commit 34a3b1a

6 files changed

Lines changed: 39 additions & 80 deletions

File tree

src/environment/environment.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,14 @@ mod tests {
167167
let global_func = Function {
168168
name: "global".to_string(),
169169
kind: Type::TVoid,
170-
params: None,
170+
params: Vec::new(),
171171
body: None,
172172
};
173173

174174
let local_func = Function {
175175
name: "local".to_string(),
176176
kind: Type::TVoid,
177-
params: None,
177+
params: Vec::new(),
178178
body: None,
179179
};
180180

src/interpreter/interpreter.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,11 +372,23 @@ fn call(
372372
}
373373

374374
// Bind arguments
375-
if let Some(params) = &func.params {
376-
for (param, arg) in params.iter().zip(args) {
377-
let arg_value = eval(arg, env)?;
378-
new_env.insert_variable(param.0.clone(), arg_value);
375+
for (i, formal_arg) in func.params.iter().enumerate() {
376+
if i >= args.len() {
377+
return Err((format!(
378+
"[Runtime Error on '{}()'] missing argument '{}'.",
379+
env.scope_name(),
380+
formal_arg.argumentName
381+
), None));
379382
}
383+
let arg_value = eval(args[i].clone(), env)?;
384+
new_env.insert_variable(formal_arg.argumentName.clone(), arg_value);
385+
}
386+
387+
if args.len() > func.params.len() {
388+
return Err((format!(
389+
"[Runtime Error on '{}()'] too many arguments.",
390+
env.scope_name()
391+
), None));
380392
}
381393

382394
// Execute function

src/ir/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl<A> Environment<A> {
115115
pub struct Function {
116116
pub name: Name,
117117
pub kind: Type,
118-
pub params: Option<Vec<(Name, Type)>>,
118+
pub params: Vec<FormalArgument>,
119119
pub body: Option<Box<Statement>>,
120120
}
121121

@@ -124,7 +124,7 @@ impl Function {
124124
return Function {
125125
name: "__main__".to_string(),
126126
kind: Type::TVoid,
127-
params: None,
127+
params: Vec::new(),
128128
body: None,
129129
};
130130
}

src/parser/parser_stmt.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,10 @@ fn parse_function_definition_statement(input: &str) -> IResult<&str, Statement>
132132
parse_block
133133
)),
134134
|(_, name, args, _, t, block)| {
135-
let params = args
136-
.into_iter()
137-
.map(|f| (f.argumentName, f.argumentType))
138-
.collect::<Vec<_>>();
139-
140135
Statement::FuncDef(Function {
141136
name: name.to_string(),
142137
kind: t,
143-
params: Some(params),
138+
params: args,
144139
body: Some(Box::new(block))
145140
})
146141
}
@@ -260,7 +255,7 @@ mod tests {
260255
let expected = Statement::FuncDef(Function {
261256
name: "f".to_string(),
262257
kind: Type::TInteger,
263-
params: Some(vec![("x".to_string(), Type::TInteger)]),
258+
params: vec![FormalArgument::new("x".to_string(), Type::TInteger)],
264259
body: Some(Box::new(Statement::Block(vec![
265260
Statement::Assignment("x".to_string(), Box::new(Expression::CInt(1)))
266261
]))),

src/tc/type_checker.rs

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::environment::environment::Environment;
2-
use crate::ir::ast::{Expression, Name, Statement, Type};
2+
use crate::ir::ast::{Expression, Name, Statement, Type, Function, FormalArgument};
33

44
type ErrorMessage = String;
55

@@ -114,11 +114,12 @@ pub fn check_stmt(
114114
Statement::FuncDef(function) => {
115115
let mut new_env = env.clone();
116116
new_env.push();
117-
if let Some(params) = function.params.clone() {
118-
for (param_name, param_type) in params {
119-
new_env.map_variable(param_name, param_type)
120-
}
117+
118+
// Since params is now a Vec<FormalArgument>, we can iterate directly
119+
for formal_arg in function.params.iter() {
120+
new_env.map_variable(formal_arg.argumentName.clone(), formal_arg.argumentType.clone());
121121
}
122+
122123
if let Some(body) = function.body.clone() {
123124
new_env = check_stmt(*body, &new_env)?;
124125
}
@@ -207,55 +208,6 @@ pub fn check_stmt(
207208
// }
208209
// }
209210

210-
// fn check_func_call(
211-
// name: String,
212-
// args: Vec<Expression>,
213-
// env: &Environment<Type>,
214-
// ) -> Result<Type, ErrorMessage> {
215-
// match check_var_name(name.clone(), env, false) {
216-
// Ok(Type::TFunction(kind, type_vec)) => {
217-
// if args.len() != type_vec.len() {
218-
// return Err(format!(
219-
// "[Type Error on '{}()'] '{}()' expected {} arguments, found {}.",
220-
// env.scope_name(),
221-
// name,
222-
// type_vec.len(),
223-
// args.len()
224-
// ));
225-
// }
226-
227-
// for (arg, param_type) in args.iter().zip(type_vec) {
228-
// let arg_type = check_exp(arg.clone(), env)?;
229-
// if arg_type != param_type {
230-
// return Err(format!("[Type Error on '{}()'] '{}()' has mismatched arguments: expected '{:?}', found '{:?}'.", env.scope_name(), name, param_type, arg_type));
231-
// }
232-
// }
233-
234-
// Ok(kind.unwrap())
235-
// }
236-
// _ => Err(format!(
237-
// "[Name Error on '{}()'] '{}()' is not defined.",
238-
// env.scope_name(),
239-
// name
240-
// )),
241-
// }
242-
// }
243-
244-
// fn check_duplicate_params(params: &Vec<(Name, Type)>) -> Result<(), ErrorMessage> {
245-
// let mut seen_params = std::collections::HashSet::new();
246-
247-
// for (name, _) in params {
248-
// if !seen_params.insert(name.clone()) {
249-
// return Err(format!(
250-
// "[Parameter Error] Duplicate parameter name '{}'",
251-
// name
252-
// ));
253-
// }
254-
// }
255-
256-
// Ok(())
257-
// }
258-
259211
fn check_var_name(name: Name, env: &Environment<Type>, scoped: bool) -> Result<Type, ErrorMessage> {
260212
let var_type = env.lookup(&name);
261213
match var_type {
@@ -773,10 +725,10 @@ mod tests {
773725
let func = FuncDef(Function {
774726
name: "add".to_string(),
775727
kind: Type::TInteger,
776-
params: Some(vec![
777-
("a".to_string(), TInteger),
778-
("b".to_string(), TInteger),
779-
]),
728+
params: vec![
729+
FormalArgument::new("a".to_string(), Type::TInteger),
730+
FormalArgument::new("b".to_string(), Type::TInteger),
731+
],
780732
body: Some(Box::new(Return(Box::new(Add(
781733
Box::new(Var("a".to_string())),
782734
Box::new(Var("b".to_string())),
@@ -916,14 +868,14 @@ mod tests {
916868
let global_func = Function {
917869
name: "global".to_string(),
918870
kind: Type::TVoid,
919-
params: None,
871+
params: Vec::new(),
920872
body: None,
921873
};
922874

923875
let local_func = Function {
924876
name: "local".to_string(),
925877
kind: Type::TVoid,
926-
params: None,
878+
params: Vec::new(),
927879
body: None,
928880
};
929881

tests/parser_tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ mod statement_tests {
213213
let input = "def add(x: Int, y: Int) -> Int: return x + y; end";
214214
let expected = Statement::FuncDef(Function {
215215
name: "add".to_string(),
216-
kind: Some(Type::TInteger),
217-
params: Some(vec![
218-
("x".to_string(), Type::TInteger),
219-
("y".to_string(), Type::TInteger),
220-
]),
216+
kind: Type::TInteger,
217+
params: vec![
218+
FormalArgument::new("x".to_string(), Type::TInteger),
219+
FormalArgument::new("y".to_string(), Type::TInteger),
220+
],
221221
body: Some(Box::new(Statement::Block(vec![Statement::Return(Box::new(
222222
Expression::Add(
223223
Box::new(Expression::Var("x".to_string())),

0 commit comments

Comments
 (0)