From 6353d4f239eebefc3032b4be517475db8ce2ea1e Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 3 Feb 2021 01:52:33 -0600 Subject: [PATCH] expand ast --- example | 10 +++++----- rustfmt.toml | 2 ++ src/ast.rs | 15 +++++++++++++-- src/main.rs | 4 ++-- src/{hoas.rs => name_res.rs} | 19 ++++++++++++------- src/parser.lalrpop | 15 +++++++++++++-- src/type_check.rs | 0 7 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 rustfmt.toml rename src/{hoas.rs => name_res.rs} (86%) create mode 100644 src/type_check.rs diff --git a/example b/example index b6048ce..5fe0bb6 100644 --- a/example +++ b/example @@ -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(); } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..59b23ea --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 100 +wrap_comments = true diff --git a/src/ast.rs b/src/ast.rs index 8d1131f..56f0099 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -18,14 +18,22 @@ pub struct Mod { #[derive(Debug)] pub struct Func { pub name: Ident, + pub args: Vec, pub stmts: Vec, - pub ret: Expr, + pub ret: Option, +} + +#[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); diff --git a/src/main.rs b/src/main.rs index 7085f4e..4056392 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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 { diff --git a/src/hoas.rs b/src/name_res.rs similarity index 86% rename from src/hoas.rs rename to src/name_res.rs index aa124dd..ee7ddcb 100644 --- a/src/hoas.rs +++ b/src/name_res.rs @@ -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; type Scopes = Vec>; -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), } } diff --git a/src/parser.lalrpop b/src/parser.lalrpop index c26e968..f7bde3c 100644 --- a/src/parser.lalrpop +++ b/src/parser.lalrpop @@ -9,11 +9,15 @@ pub Program: Program = { Decls: Vec = Decl*; Decl: Decl = { - "fn" "{" "}" => { Decl::Func(Func{ name, stmts, ret }) }, + "fn" "(" > ")" "{" "}" => { Decl::Func(Func{ name, args, stmts, ret: Some(ret), }) }, + "fn" "(" > ")" "{" "}" => { Decl::Func(Func{ name, args, stmts, ret: None, }) }, }; +Arg: Arg = ":" => Arg { name, ty }; + Stmt: Stmt = { ";" => Stmt::Expr(expr), + "let" "=" ";" => Stmt::Let(name, expr), "return" ";" => 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::().unwrap(); // Sep: Vec = { - )*> => match e { + *> => match e { None => v, Some(e) => { let mut v = v; @@ -46,3 +55,5 @@ Sep: Vec = { } } }; + +Sep1: T = D => t; diff --git a/src/type_check.rs b/src/type_check.rs new file mode 100644 index 0000000..e69de29