This commit is contained in:
Michael Zhang 2021-01-24 08:06:16 -06:00
parent cbd9dc2986
commit 9747990c12
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
9 changed files with 119 additions and 40 deletions

1
Cargo.lock generated
View file

@ -324,6 +324,7 @@ dependencies = [
"lalrpop-util",
"lazy_static",
"parking_lot",
"petgraph",
"regex",
"structopt",
"target-lexicon",

View file

@ -12,6 +12,7 @@ cranelift-object = "0.69.0"
lalrpop-util = "0.19.4"
lazy_static = "1.4.0"
parking_lot = "0.11.1"
petgraph = "0.5.1"
regex = "1.4.3"
structopt = "0.3.21"
target-lexicon = "0.11.1"

View file

@ -1,7 +1,11 @@
fn main
{
urmom();
isEven();
5
}
fn urmom { 12 }
fn isEven { isOdd }
fn isOdd { isEven }

View file

@ -25,6 +25,7 @@ pub enum Stmt {
pub enum Expr {
Seq(Vec<Stmt>, Box<Expr>),
FuncCall(Ident),
Var(Ident),
Lit(Lit),
}
@ -34,9 +35,7 @@ pub enum Lit {
}
#[derive(Debug)]
pub enum Type {
}
pub enum Type {}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Ident(pub String);

View file

@ -1,34 +0,0 @@
use std::collections::HashMap;
use crate::ast::{Program, Decl, Func, Type, Ident};
use crate::utils::Id;
#[derive(Debug)]
pub struct Namespaces {
funcs: HashMap<Id, Func>,
types: HashMap<Id, Type>,
func_names: HashMap<Ident, Id>,
type_names: HashMap<Ident, Id>,
}
impl Namespaces {
pub fn create(program: Program) -> Self {
let mut funcs = HashMap::new();
let mut types = HashMap::new();
let mut func_names = HashMap::new();
let mut type_names = HashMap::new();
for decl in program.decls {
match decl {
Decl::Func(func) => {
let id = Id::default();
func_names.insert(func.name.clone(), id);
funcs.insert(id, func);
}
}
}
Namespaces { funcs, types, func_names, type_names }
}
}

106
src/hoas.rs Normal file
View file

@ -0,0 +1,106 @@
use std::collections::{HashMap, HashSet};
use petgraph::{algo, graphmap::DiGraphMap};
use crate::ast::*;
use crate::utils::Id;
type Graph = DiGraphMap<Id, ()>;
type Scopes = Vec<HashSet<String>>;
#[derive(Debug)]
pub struct Namespaces {
funcs: HashMap<Id, Func>,
types: HashMap<Id, Type>,
func_names: HashMap<String, Id>,
type_names: HashMap<String, Id>,
}
impl Namespaces {
pub fn create(program: Program) -> Self {
let mut funcs = HashMap::new();
let mut types = HashMap::new();
let mut func_names = HashMap::new();
let mut type_names = HashMap::new();
for decl in program.decls {
match decl {
Decl::Func(func) => {
let id = Id::default();
func_names.insert(func.name.0.clone(), id);
funcs.insert(id, func);
}
}
}
Namespaces {
funcs,
types,
func_names,
type_names,
}
}
pub fn name_resolution(&self) {
let mut graph = Graph::new();
for (id, func) in self.funcs.iter() {
walk_func(&mut graph, &self, *id, func);
}
println!("graph: {:?}", graph);
let scc = algo::tarjan_scc(&graph);
for group in scc.iter() {
println!("group: {:?}", group);
}
}
}
fn walk_func(g: &mut Graph, n: &Namespaces, src: Id, f: &Func) {
let mut scopes = Vec::new();
scopes.push(HashSet::new());
for s in f.stmts.iter() {
walk_stmt(g, n, src, &mut scopes, s);
}
walk_expr(g, n, src, &mut scopes, &f.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),
}
}
fn walk_expr(g: &mut Graph, n: &Namespaces, src: Id, sc: &mut Scopes, e: &Expr) {
match e {
Expr::FuncCall(id) | Expr::Var(id) => {
let id = &id.0;
let mut found = false;
for scope in sc.iter().rev() {
if scope.contains(id) {
found = true;
break;
}
}
if !found {
if let Some(target_id) = n.func_names.get(id) {
g.add_node(src);
g.add_node(*target_id);
g.add_edge(src, *target_id, ());
}
}
}
Expr::Seq(stmts, e) => {
sc.push(HashSet::new());
for s in stmts {
walk_stmt(g, n, src, sc, s);
}
walk_expr(g, n, src, sc, e);
sc.pop();
}
Expr::Lit(_) => {}
}
}

View file

@ -1,6 +1,6 @@
mod ast;
mod hoas;
mod parser;
mod hir;
mod utils;
use std::fs::{File, OpenOptions};
@ -11,7 +11,7 @@ use anyhow::Result;
use cranelift::prelude::*;
use structopt::StructOpt;
use crate::hir::Namespaces;
use crate::hoas::Namespaces;
#[derive(StructOpt)]
struct Opt {
@ -35,6 +35,7 @@ fn main() -> Result<()> {
let namespaces = Namespaces::create(parsed);
println!("namespaces: {:?}", namespaces);
namespaces.name_resolution();
let isa = {
use std::str::FromStr;

View file

@ -21,6 +21,7 @@ BlockExpr: Expr = "{" <stmts:Stmt*> <expr:Expr> "}" => Expr::Seq(stmts, Box::new
Expr: Expr = {
<name:Ident> "(" ")" => Expr::FuncCall(name),
Ident => Expr::Var(<>),
Lit => Expr::Lit(<>),
};

View file

@ -8,7 +8,7 @@ lazy_static! {
static ref N: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Id(usize);
impl Default for Id {