[fine] Environments for functions
Fun times.
This commit is contained in:
parent
308114f8cf
commit
efd0685f41
3 changed files with 81 additions and 3 deletions
|
|
@ -120,7 +120,7 @@ impl<'a> std::ops::IndexMut<TreeRef> for SyntaxTree<'a> {
|
|||
pub enum TreeKind {
|
||||
Error,
|
||||
File,
|
||||
FunDecl,
|
||||
FunctionDecl,
|
||||
ParamList,
|
||||
Parameter,
|
||||
TypeExpression,
|
||||
|
|
@ -488,7 +488,7 @@ fn function(p: &mut CParser) {
|
|||
block(p);
|
||||
}
|
||||
|
||||
p.end(m, TreeKind::FunDecl);
|
||||
p.end(m, TreeKind::FunctionDecl);
|
||||
}
|
||||
|
||||
fn param_list(p: &mut CParser) {
|
||||
|
|
|
|||
|
|
@ -369,6 +369,7 @@ impl<'a> Semantics<'a> {
|
|||
|
||||
let result = match tree.kind {
|
||||
TreeKind::LetStatement => self.environment_of_let(parent, tree),
|
||||
TreeKind::FunctionDecl => self.environment_of_func(parent, tree),
|
||||
|
||||
// TODO: MORE Things that introduce an environment!
|
||||
_ => parent,
|
||||
|
|
@ -404,6 +405,44 @@ impl<'a> Semantics<'a> {
|
|||
EnvironmentRef::new(environment)
|
||||
}
|
||||
|
||||
fn environment_of_func(&self, parent: EnvironmentRef, tree: &Tree) -> EnvironmentRef {
|
||||
let Some(param_list) = tree.nth_tree(2) else {
|
||||
return parent; // SE
|
||||
};
|
||||
let param_list = &self.syntax_tree[param_list];
|
||||
if param_list.kind != TreeKind::ParamList {
|
||||
return parent; // SE
|
||||
}
|
||||
|
||||
let mut environment = Environment::new(Some(parent));
|
||||
for child in param_list.children.iter() {
|
||||
let Child::Tree(ct) = child else {
|
||||
continue;
|
||||
};
|
||||
let param = &self.syntax_tree[*ct];
|
||||
if param.kind != TreeKind::Parameter {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(param_name) = param.nth_token(0) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let declaration_type = if let Some(type_expression) = param.nth_tree(2) {
|
||||
self.type_of(type_expression)
|
||||
.expect("the type expression should yield *some* type here")
|
||||
} else {
|
||||
Type::Error
|
||||
};
|
||||
|
||||
environment
|
||||
.declarations
|
||||
.insert(param_name.as_str().into(), Declaration { declaration_type });
|
||||
}
|
||||
|
||||
EnvironmentRef::new(environment)
|
||||
}
|
||||
|
||||
pub fn type_of(&self, t: TreeRef) -> Option<Type> {
|
||||
match self.types.borrow().get(&t) {
|
||||
None => (),
|
||||
|
|
@ -553,7 +592,16 @@ impl<'a> Semantics<'a> {
|
|||
|
||||
fn type_of_type_expr(&self, tree: &Tree) -> Option<Type> {
|
||||
assert_eq!(tree.kind, TreeKind::TypeExpression);
|
||||
Some(Type::Error)
|
||||
|
||||
// TODO: This will *clearly* need to get better.
|
||||
let token = tree.nth_token(0)?;
|
||||
match token.as_str() {
|
||||
"f64" => Some(Type::F64),
|
||||
"string" => Some(Type::String),
|
||||
"bool" => Some(Type::Bool),
|
||||
"()" => Some(Type::Nothing),
|
||||
_ => Some(Type::Error),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_of_block(&self, tree: &Tree) -> Option<Type> {
|
||||
|
|
|
|||
30
fine/tests/expression/argument.fine
Normal file
30
fine/tests/expression/argument.fine
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// @concrete:
|
||||
// | File
|
||||
// | FunctionDecl
|
||||
// | Fun:'"fun"'
|
||||
// | Identifier:'"foo"'
|
||||
// | ParamList
|
||||
// | LeftParen:'"("'
|
||||
// | Parameter
|
||||
// | Identifier:'"x"'
|
||||
// | Colon:'":"'
|
||||
// | TypeExpression
|
||||
// | Identifier:'"f64"'
|
||||
// | RightParen:'")"'
|
||||
// | Block
|
||||
// | LeftBrace:'"{"'
|
||||
// | ExpressionStatement
|
||||
// | BinaryExpression
|
||||
// | Identifier
|
||||
// | Identifier:'"x"'
|
||||
// | Plus:'"+"'
|
||||
// | LiteralExpression
|
||||
// | Number:'"7"'
|
||||
// | RightBrace:'"}"'
|
||||
// |
|
||||
|
||||
fun foo(x: f64) {
|
||||
x + 7
|
||||
}
|
||||
|
||||
// @type: 613 f64
|
||||
Loading…
Add table
Add a link
Reference in a new issue