[fine] Gobs of work

- Assertion improvements
- Type check function calls
- Functions in the environment
- Compile function calls
This commit is contained in:
John Doty 2024-01-13 08:12:39 -08:00
parent 9d226b205d
commit 5ebede4a21
6 changed files with 539 additions and 142 deletions

View file

@ -138,6 +138,7 @@ pub enum TreeKind {
BinaryExpression,
IfStatement,
Identifier,
ReturnType,
}
pub struct Tree<'a> {
@ -169,6 +170,31 @@ impl<'a> Tree<'a> {
.flatten()
}
pub fn child_trees<'b>(&'b self) -> impl Iterator<Item = TreeRef> + 'b {
self.children.iter().filter_map(|c| match c {
Child::Tree(t) => Some(*t),
_ => None,
})
}
pub fn child_of_kind(&self, s: &SyntaxTree, kind: TreeKind) -> Option<TreeRef> {
self.children
.iter()
.filter_map(|c| match c {
Child::Tree(t) => Some(*t),
_ => None,
})
.find(|c| s[*c].kind == kind)
}
pub fn child_tree_of_kind<'b>(
&'b self,
s: &'b SyntaxTree<'a>,
kind: TreeKind,
) -> Option<&'b Tree<'a>> {
self.child_of_kind(s, kind).map(|t| &s[t])
}
pub fn dump(&self, tree: &SyntaxTree<'a>, with_positions: bool, output: &mut String) {
let _ = write!(output, "{:?}", self.kind);
if with_positions {
@ -481,8 +507,8 @@ fn function(p: &mut CParser) {
if p.at(TokenKind::LeftParen) {
param_list(p);
}
if p.eat(TokenKind::Arrow) {
type_expr(p);
if p.at(TokenKind::Arrow) {
return_type(p);
}
if p.at(TokenKind::LeftBrace) {
block(p);
@ -525,6 +551,19 @@ fn parameter(p: &mut CParser) {
p.end(m, TreeKind::Parameter);
}
fn return_type(p: &mut CParser) {
assert!(p.at(TokenKind::Arrow));
let m = p.start();
p.expect(
TokenKind::Arrow,
"function return type starts with an arrow",
);
type_expr(p);
p.end(m, TreeKind::ReturnType);
}
fn type_expr(p: &mut CParser) {
let m = p.start();
// TODO: Other kinds of type expressions probably!