a
This commit is contained in:
parent
cbd9dc2986
commit
9747990c12
9 changed files with 119 additions and 40 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -324,6 +324,7 @@ dependencies = [
|
|||
"lalrpop-util",
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
"petgraph",
|
||||
"regex",
|
||||
"structopt",
|
||||
"target-lexicon",
|
||||
|
|
|
@ -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"
|
||||
|
|
4
example
4
example
|
@ -1,7 +1,11 @@
|
|||
fn main
|
||||
{
|
||||
urmom();
|
||||
isEven();
|
||||
5
|
||||
}
|
||||
|
||||
fn urmom { 12 }
|
||||
|
||||
fn isEven { isOdd }
|
||||
fn isOdd { isEven }
|
||||
|
|
|
@ -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);
|
||||
|
|
34
src/hir.rs
34
src/hir.rs
|
@ -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
106
src/hoas.rs
Normal 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(_) => {}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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(<>),
|
||||
};
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue