expand ast

This commit is contained in:
Michael Zhang 2021-02-03 01:52:33 -06:00
parent acebeaa332
commit 6353d4f239
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
7 changed files with 47 additions and 18 deletions

10
example
View file

@ -1,10 +1,10 @@
fn main {
fn main() {
let x = ();
urmom();
isEven();
5
}
fn urmom { 12 }
fn urmom(x: ()) { return (); }
fn isEven { isOdd }
fn isOdd { isEven }
fn isEven() { return isOdd(); }
fn isOdd() { return isEven(); }

2
rustfmt.toml Normal file
View file

@ -0,0 +1,2 @@
max_width = 100
wrap_comments = true

View file

@ -18,14 +18,22 @@ pub struct Mod {
#[derive(Debug)]
pub struct Func {
pub name: Ident,
pub args: Vec<Arg>,
pub stmts: Vec<Stmt>,
pub ret: Expr,
pub ret: Option<Expr>,
}
#[derive(Debug)]
pub struct Arg {
pub name: Ident,
pub ty: Type,
}
#[derive(Debug)]
pub enum Stmt {
Expr(Expr),
Return(Expr),
Let(Ident, Expr),
}
#[derive(Debug)]
@ -38,11 +46,14 @@ pub enum Expr {
#[derive(Debug)]
pub enum Lit {
Unit,
Int(i64),
}
#[derive(Debug)]
pub enum Type {}
pub enum Type {
Unit,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Ident(pub String);

View file

@ -1,5 +1,5 @@
mod ast;
mod hoas;
mod name_res;
mod parser;
mod utils;
@ -11,7 +11,7 @@ use anyhow::Result;
use cranelift::prelude::*;
use structopt::StructOpt;
use crate::hoas::Namespaces;
use crate::name_res::Namespaces;
#[derive(StructOpt)]
struct Opt {

View file

@ -1,3 +1,9 @@
//! Name resolution
//! ===
//!
//! This module deals with name resolution, ultimately going from a bunch of
//! different files into a single expression tree ready for type-checking.
use std::collections::{HashMap, HashSet};
use petgraph::{algo, graphmap::DiGraphMap};
@ -8,9 +14,7 @@ use crate::utils::Id;
type Graph = DiGraphMap<Id, ()>;
type Scopes = Vec<HashSet<String>>;
pub enum HExpr {
}
pub enum HExpr {}
#[derive(Debug)]
pub struct Namespaces {
@ -35,8 +39,7 @@ impl Namespaces {
func_names.insert(func.name.0.clone(), id);
funcs.insert(id, func);
}
Decl::Mod(_mod) => {
}
Decl::Mod(_mod) => {}
}
}
@ -69,14 +72,16 @@ fn walk_func(g: &mut Graph, n: &Namespaces, src: Id, f: &Func) {
for s in f.stmts.iter() {
walk_stmt(g, n, src, &mut scopes, s);
}
walk_expr(g, n, src, &mut scopes, &f.ret);
if let Some(ret) = &f.ret {
walk_expr(g, n, src, &mut scopes, ret);
}
scopes.pop();
assert!(scopes.is_empty());
}
fn walk_stmt(g: &mut Graph, n: &Namespaces, src: Id, sc: &mut Scopes, s: &Stmt) {
match s {
Stmt::Expr(e) | Stmt::Return(e) => walk_expr(g, n, src, sc, e),
Stmt::Let(_, e) | Stmt::Expr(e) | Stmt::Return(e) => walk_expr(g, n, src, sc, e),
}
}

View file

@ -9,11 +9,15 @@ pub Program: Program = {
Decls: Vec<Decl> = Decl*;
Decl: Decl = {
"fn" <name:Ident> "{" <stmts:Stmt*> <ret:Expr> "}" => { Decl::Func(Func{ name, stmts, ret }) },
"fn" <name:Ident> "(" <args:Sep<Arg, ",">> ")" "{" <stmts:Stmt*> <ret:Expr> "}" => { Decl::Func(Func{ name, args, stmts, ret: Some(ret), }) },
"fn" <name:Ident> "(" <args:Sep<Arg, ",">> ")" "{" <stmts:Stmt*> "}" => { Decl::Func(Func{ name, args, stmts, ret: None, }) },
};
Arg: Arg = <name:Ident> ":" <ty:Type> => Arg { name, ty };
Stmt: Stmt = {
<expr:Expr> ";" => Stmt::Expr(expr),
"let" <name:Ident> "=" <expr:Expr> ";" => Stmt::Let(name, expr),
"return" <expr:Expr> ";" => Stmt::Return(expr),
};
@ -26,9 +30,14 @@ Expr: Expr = {
};
Lit: Lit = {
"(" ")" => Lit::Unit,
Int => Lit::Int(<>),
};
Type: Type = {
"(" ")" => Type::Unit,
};
//
Ident: Ident = r"[A-Za-z][A-Za-z0-9_]*|_[A-Za-z0-9_]+" => Ident(<>.to_owned());
@ -37,7 +46,7 @@ Int: i64 = r"[0-9]+" => <>.parse::<i64>().unwrap();
//
Sep<T, D>: Vec<T> = {
<v:(<T> <D>)*> <e:T?> => match e {
<v:Sep1<T, D>*> <e:T?> => match e {
None => v,
Some(e) => {
let mut v = v;
@ -46,3 +55,5 @@ Sep<T, D>: Vec<T> = {
}
}
};
Sep1<T, D>: T = <t:T> D => t;

0
src/type_check.rs Normal file
View file