1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use std::sync::Arc;
use std::collections::HashMap;
use ast;
use intrinsics;
use Module;
use Type;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Lt {
Arg(usize),
Return,
Default,
}
#[derive(Clone, PartialEq, Debug)]
pub struct Dfn {
pub lts: Vec<Lt>,
pub tys: Vec<Type>,
pub ret: Type,
}
impl Dfn {
pub fn new(f: &ast::Function) -> Dfn {
let mut lts: Vec<Lt> = vec![];
let mut tys: Vec<Type> = vec![];
'next_arg: for arg in &f.args {
tys.push(arg.ty.clone());
if let Some(ref lt) = arg.lifetime {
if **lt == "return" {
lts.push(Lt::Return);
continue 'next_arg;
}
for (i, arg2) in f.args.iter().enumerate() {
if **arg2.name == **lt {
lts.push(Lt::Arg(i));
continue 'next_arg;
}
}
panic!("Could not find argument `{}`", lt);
} else {
lts.push(Lt::Default);
}
}
Dfn {
lts: lts,
tys: tys,
ret: f.ret.clone(),
}
}
pub fn returns(&self) -> bool { self.ret != Type::Void }
}
pub struct Prelude {
pub functions: HashMap<Arc<String>, usize>,
pub list: Vec<Dfn>,
pub namespaces: Vec<(Arc<Vec<Arc<String>>>, Arc<String>)>,
}
impl Prelude {
pub fn insert(&mut self, namespace: Arc<Vec<Arc<String>>>, name: Arc<String>, f: Dfn) {
let n = self.list.len();
self.functions.insert(name.clone(), n);
self.list.push(f);
self.namespaces.push((namespace, name));
}
pub fn intrinsic(&mut self, name: Arc<String>, index: usize, f: Dfn) {
let n = self.list.len();
assert!(n == index, "{}", name);
self.functions.insert(name.clone(), n);
self.list.push(f);
self.namespaces.push((Arc::new(vec![]), name));
}
pub fn new() -> Prelude {
Prelude {
functions: HashMap::new(),
list: vec![],
namespaces: vec![],
}
}
pub fn new_intrinsics() -> Prelude {
let mut prelude = Prelude::new();
intrinsics::standard(&mut prelude);
prelude
}
pub fn from_module(module: &Module) -> Prelude {
let mut prelude = Prelude::new();
intrinsics::standard(&mut prelude);
for f in &*module.ext_prelude {
prelude.insert(Arc::new(vec![]), f.name.clone(), f.p.clone());
}
for f in &module.functions {
prelude.insert(f.namespace.clone(), f.name.clone(), Dfn::new(f));
}
prelude
}
}