[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 {
|
pub enum TreeKind {
|
||||||
Error,
|
Error,
|
||||||
File,
|
File,
|
||||||
FunDecl,
|
FunctionDecl,
|
||||||
ParamList,
|
ParamList,
|
||||||
Parameter,
|
Parameter,
|
||||||
TypeExpression,
|
TypeExpression,
|
||||||
|
|
@ -488,7 +488,7 @@ fn function(p: &mut CParser) {
|
||||||
block(p);
|
block(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.end(m, TreeKind::FunDecl);
|
p.end(m, TreeKind::FunctionDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_list(p: &mut CParser) {
|
fn param_list(p: &mut CParser) {
|
||||||
|
|
|
||||||
|
|
@ -369,6 +369,7 @@ impl<'a> Semantics<'a> {
|
||||||
|
|
||||||
let result = match tree.kind {
|
let result = match tree.kind {
|
||||||
TreeKind::LetStatement => self.environment_of_let(parent, tree),
|
TreeKind::LetStatement => self.environment_of_let(parent, tree),
|
||||||
|
TreeKind::FunctionDecl => self.environment_of_func(parent, tree),
|
||||||
|
|
||||||
// TODO: MORE Things that introduce an environment!
|
// TODO: MORE Things that introduce an environment!
|
||||||
_ => parent,
|
_ => parent,
|
||||||
|
|
@ -404,6 +405,44 @@ impl<'a> Semantics<'a> {
|
||||||
EnvironmentRef::new(environment)
|
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> {
|
pub fn type_of(&self, t: TreeRef) -> Option<Type> {
|
||||||
match self.types.borrow().get(&t) {
|
match self.types.borrow().get(&t) {
|
||||||
None => (),
|
None => (),
|
||||||
|
|
@ -553,7 +592,16 @@ impl<'a> Semantics<'a> {
|
||||||
|
|
||||||
fn type_of_type_expr(&self, tree: &Tree) -> Option<Type> {
|
fn type_of_type_expr(&self, tree: &Tree) -> Option<Type> {
|
||||||
assert_eq!(tree.kind, TreeKind::TypeExpression);
|
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> {
|
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