forked from M-Labs/nac3
simple implementation of classes
This commit is contained in:
parent
bf1769cef6
commit
4939ff4dbd
|
@ -114,10 +114,28 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
let symbol = {
|
let symbol = {
|
||||||
// make sure this lock guard is dropped at the end of this scope...
|
// make sure this lock guard is dropped at the end of this scope...
|
||||||
let def = definition.read();
|
let def = definition.read();
|
||||||
if let TopLevelDef::Function { instance_to_symbol, .. } = &*def {
|
match &*def {
|
||||||
instance_to_symbol.get(&key).cloned()
|
TopLevelDef::Function { instance_to_symbol, .. } => {
|
||||||
} else {
|
instance_to_symbol.get(&key).cloned()
|
||||||
unreachable!()
|
}
|
||||||
|
TopLevelDef::Class { methods, .. } => {
|
||||||
|
// TODO: what about other fields that require alloca?
|
||||||
|
let mut fun_id = None;
|
||||||
|
for (name, _, id) in methods.iter() {
|
||||||
|
if name == "__init__" {
|
||||||
|
fun_id = Some(*id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let fun_id = fun_id.unwrap();
|
||||||
|
|
||||||
|
let ty = self.get_llvm_type(fun.0.ret).into_pointer_type();
|
||||||
|
let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap();
|
||||||
|
let zelf = self.builder.build_alloca(zelf_ty, "alloca").into();
|
||||||
|
let mut sign = fun.0.clone();
|
||||||
|
sign.ret = self.primitives.none;
|
||||||
|
self.gen_call(Some((fun.0.ret, zelf)), (&sign, fun_id), params);
|
||||||
|
return Some(zelf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
|
@ -164,7 +182,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let signature = FunSignature {
|
let mut signature = FunSignature {
|
||||||
args: fun
|
args: fun
|
||||||
.0
|
.0
|
||||||
.args
|
.args
|
||||||
|
@ -186,6 +204,13 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(obj) = &obj {
|
||||||
|
signature.args.insert(
|
||||||
|
0,
|
||||||
|
FuncArg { name: "self".into(), ty: obj.0, default_value: None },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let unifier = (unifier.get_shared_unifier(), *primitives);
|
let unifier = (unifier.get_shared_unifier(), *primitives);
|
||||||
|
|
||||||
task = Some(CodeGenTask {
|
task = Some(CodeGenTask {
|
||||||
|
@ -209,7 +234,11 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let fun_val = self.module.get_function(&symbol).unwrap_or_else(|| {
|
let fun_val = self.module.get_function(&symbol).unwrap_or_else(|| {
|
||||||
let params = fun.0.args.iter().map(|arg| self.get_llvm_type(arg.ty)).collect_vec();
|
let mut args = fun.0.args.clone();
|
||||||
|
if let Some(obj) = &obj {
|
||||||
|
args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None });
|
||||||
|
}
|
||||||
|
let params = args.iter().map(|arg| self.get_llvm_type(arg.ty)).collect_vec();
|
||||||
let fun_ty = if self.unifier.unioned(fun.0.ret, self.primitives.none) {
|
let fun_ty = if self.unifier.unioned(fun.0.ret, self.primitives.none) {
|
||||||
self.ctx.void_type().fn_type(¶ms, false)
|
self.ctx.void_type().fn_type(¶ms, false)
|
||||||
} else {
|
} else {
|
||||||
|
@ -227,7 +256,11 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
mapping.insert(k.name, self.gen_symbol_val(&k.default_value.unwrap()));
|
mapping.insert(k.name, self.gen_symbol_val(&k.default_value.unwrap()));
|
||||||
}
|
}
|
||||||
// reorder the parameters
|
// reorder the parameters
|
||||||
let params = fun.0.args.iter().map(|arg| mapping.remove(&arg.name).unwrap()).collect_vec();
|
let mut params =
|
||||||
|
fun.0.args.iter().map(|arg| mapping.remove(&arg.name).unwrap()).collect_vec();
|
||||||
|
if let Some(obj) = obj {
|
||||||
|
params.insert(0, obj.1);
|
||||||
|
}
|
||||||
self.builder.build_call(fun_val, ¶ms, "call").try_as_basic_value().left()
|
self.builder.build_call(fun_val, ¶ms, "call").try_as_basic_value().left()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,26 +640,53 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
phi.as_basic_value()
|
phi.as_basic_value()
|
||||||
}
|
}
|
||||||
ExprKind::Call { func, args, keywords } => {
|
ExprKind::Call { func, args, keywords } => {
|
||||||
if let ExprKind::Name { id, .. } = &func.as_ref().node {
|
let mut params =
|
||||||
// TODO: handle primitive casts and function pointers
|
args.iter().map(|arg| (None, self.gen_expr(arg).unwrap())).collect_vec();
|
||||||
let fun = self.resolver.get_identifier_def(&id).expect("Unknown identifier");
|
let kw_iter = keywords.iter().map(|kw| {
|
||||||
let mut params =
|
(
|
||||||
args.iter().map(|arg| (None, self.gen_expr(arg).unwrap())).collect_vec();
|
Some(kw.node.arg.as_ref().unwrap().clone()),
|
||||||
let kw_iter = keywords.iter().map(|kw| {
|
self.gen_expr(&kw.node.value).unwrap(),
|
||||||
(
|
)
|
||||||
Some(kw.node.arg.as_ref().unwrap().clone()),
|
});
|
||||||
self.gen_expr(&kw.node.value).unwrap(),
|
params.extend(kw_iter);
|
||||||
)
|
let signature = self
|
||||||
});
|
.unifier
|
||||||
params.extend(kw_iter);
|
.get_call_signature(*self.calls.get(&expr.location.into()).unwrap())
|
||||||
let signature = self
|
.unwrap();
|
||||||
.unifier
|
match &func.as_ref().node {
|
||||||
.get_call_signature(*self.calls.get(&expr.location.into()).unwrap())
|
ExprKind::Name { id, .. } => {
|
||||||
.unwrap();
|
// TODO: handle primitive casts and function pointers
|
||||||
return self.gen_call(None, (&signature, fun), params);
|
let fun =
|
||||||
} else {
|
self.resolver.get_identifier_def(&id).expect("Unknown identifier");
|
||||||
// TODO: method
|
return self.gen_call(None, (&signature, fun), params);
|
||||||
unimplemented!()
|
}
|
||||||
|
ExprKind::Attribute { value, attr, .. } => {
|
||||||
|
let val = self.gen_expr(value).unwrap();
|
||||||
|
let id = if let TypeEnum::TObj { obj_id, .. } =
|
||||||
|
&*self.unifier.get_ty(value.custom.unwrap())
|
||||||
|
{
|
||||||
|
*obj_id
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
let fun_id = {
|
||||||
|
let defs = self.top_level.definitions.read();
|
||||||
|
let obj_def = defs.get(id.0).unwrap().read();
|
||||||
|
if let TopLevelDef::Class { methods, .. } = &*obj_def {
|
||||||
|
let mut fun_id = None;
|
||||||
|
for (name, _, id) in methods.iter() {
|
||||||
|
if name == attr {
|
||||||
|
fun_id = Some(*id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun_id.unwrap()
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return self.gen_call(Some((value.custom.unwrap(), val)), (&signature, fun_id), params);
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Subscript { value, slice, .. } => {
|
ExprKind::Subscript { value, slice, .. } => {
|
||||||
|
|
|
@ -341,8 +341,16 @@ pub fn gen_func<'ctx>(
|
||||||
unifier,
|
unifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut returned = false;
|
||||||
for stmt in task.body.iter() {
|
for stmt in task.body.iter() {
|
||||||
code_gen_context.gen_stmt(stmt);
|
returned = code_gen_context.gen_stmt(stmt);
|
||||||
|
if returned {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// after static analysis, only void functions can have no return at the end.
|
||||||
|
if !returned {
|
||||||
|
code_gen_context.builder.build_return(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let CodeGenContext { builder, module, .. } = code_gen_context;
|
let CodeGenContext { builder, module, .. } = code_gen_context;
|
||||||
|
|
|
@ -34,16 +34,18 @@ impl Default for TopLevelComposer {
|
||||||
impl TopLevelComposer {
|
impl TopLevelComposer {
|
||||||
/// return a composer and things to make a "primitive" symbol resolver, so that the symbol
|
/// return a composer and things to make a "primitive" symbol resolver, so that the symbol
|
||||||
/// resolver can later figure out primitive type definitions when passed a primitive type name
|
/// resolver can later figure out primitive type definitions when passed a primitive type name
|
||||||
pub fn new(builtins: Vec<(String, FunSignature)>) -> (Self, HashMap<String, DefinitionId>, HashMap<String, Type>) {
|
pub fn new(
|
||||||
|
builtins: Vec<(String, FunSignature)>,
|
||||||
|
) -> (Self, HashMap<String, DefinitionId>, HashMap<String, Type>) {
|
||||||
let primitives = Self::make_primitives();
|
let primitives = Self::make_primitives();
|
||||||
|
|
||||||
let mut definition_ast_list = {
|
let mut definition_ast_list = {
|
||||||
let top_level_def_list = vec![
|
let top_level_def_list = vec![
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(0, None, "int32"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(0, None, "int32", None))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(1, None, "int64"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(1, None, "int64", None))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(2, None, "float"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(2, None, "float", None))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(3, None, "bool"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(3, None, "bool", None))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(4, None, "none"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(4, None, "none", None))),
|
||||||
];
|
];
|
||||||
let ast_list: Vec<Option<ast::Stmt<()>>> = vec![None, None, None, None, None];
|
let ast_list: Vec<Option<ast::Stmt<()>>> = vec![None, None, None, None, None];
|
||||||
izip!(top_level_def_list, ast_list).collect_vec()
|
izip!(top_level_def_list, ast_list).collect_vec()
|
||||||
|
@ -69,10 +71,10 @@ impl TopLevelComposer {
|
||||||
let mut defined_class_name: HashSet<String> = Default::default();
|
let mut defined_class_name: HashSet<String> = Default::default();
|
||||||
let mut defined_function_name: HashSet<String> = Default::default();
|
let mut defined_function_name: HashSet<String> = Default::default();
|
||||||
let method_class: HashMap<DefinitionId, DefinitionId> = Default::default();
|
let method_class: HashMap<DefinitionId, DefinitionId> = Default::default();
|
||||||
|
|
||||||
let mut built_in_id: HashMap<String, DefinitionId> = Default::default();
|
let mut built_in_id: HashMap<String, DefinitionId> = Default::default();
|
||||||
let mut built_in_ty: HashMap<String, Type> = Default::default();
|
let mut built_in_ty: HashMap<String, Type> = Default::default();
|
||||||
|
|
||||||
for (name, sig) in builtins {
|
for (name, sig) in builtins {
|
||||||
let fun_sig = unifier.add_ty(TypeEnum::TFunc(RefCell::new(sig)));
|
let fun_sig = unifier.add_ty(TypeEnum::TFunc(RefCell::new(sig)));
|
||||||
built_in_ty.insert(name.clone(), fun_sig);
|
built_in_ty.insert(name.clone(), fun_sig);
|
||||||
|
@ -80,22 +82,20 @@ impl TopLevelComposer {
|
||||||
definition_ast_list.push((
|
definition_ast_list.push((
|
||||||
Arc::new(RwLock::new(TopLevelDef::Function {
|
Arc::new(RwLock::new(TopLevelDef::Function {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
|
simple_name: name.clone(),
|
||||||
signature: fun_sig,
|
signature: fun_sig,
|
||||||
instance_to_stmt: HashMap::new(),
|
instance_to_stmt: HashMap::new(),
|
||||||
instance_to_symbol: [("".to_string(), name.clone())]
|
instance_to_symbol: [("".to_string(), name.clone())].iter().cloned().collect(),
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
var_id: Default::default(),
|
var_id: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
})),
|
})),
|
||||||
None
|
None,
|
||||||
));
|
));
|
||||||
defined_class_method_name.insert(name.clone());
|
defined_class_method_name.insert(name.clone());
|
||||||
defined_class_name.insert(name.clone());
|
defined_class_name.insert(name.clone());
|
||||||
defined_function_name.insert(name);
|
defined_function_name.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
TopLevelComposer {
|
TopLevelComposer {
|
||||||
built_in_num: definition_ast_list.len(),
|
built_in_num: definition_ast_list.len(),
|
||||||
|
@ -160,11 +160,13 @@ impl TopLevelComposer {
|
||||||
|
|
||||||
// since later when registering class method, ast will still be used,
|
// since later when registering class method, ast will still be used,
|
||||||
// here push None temporarly, later will move the ast inside
|
// here push None temporarly, later will move the ast inside
|
||||||
|
let constructor_ty = self.unifier.get_fresh_var().0;
|
||||||
let mut class_def_ast = (
|
let mut class_def_ast = (
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(
|
Arc::new(RwLock::new(Self::make_top_level_class_def(
|
||||||
class_def_id,
|
class_def_id,
|
||||||
resolver.clone(),
|
resolver.clone(),
|
||||||
name,
|
name,
|
||||||
|
Some(constructor_ty)
|
||||||
))),
|
))),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -215,6 +217,7 @@ impl TopLevelComposer {
|
||||||
method_name.clone(),
|
method_name.clone(),
|
||||||
RwLock::new(Self::make_top_level_function_def(
|
RwLock::new(Self::make_top_level_function_def(
|
||||||
global_class_method_name,
|
global_class_method_name,
|
||||||
|
method_name.clone(),
|
||||||
// later unify with parsed type
|
// later unify with parsed type
|
||||||
dummy_method_type.0,
|
dummy_method_type.0,
|
||||||
resolver.clone(),
|
resolver.clone(),
|
||||||
|
@ -251,14 +254,7 @@ impl TopLevelComposer {
|
||||||
self.definition_ast_list.push((def, Some(ast)));
|
self.definition_ast_list.push((def, Some(ast)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// put the constructor into the def_list
|
Ok((class_name, DefinitionId(class_def_id), Some(constructor_ty)))
|
||||||
self.definition_ast_list.push((
|
|
||||||
RwLock::new(TopLevelDef::Initializer { class_id: DefinitionId(class_def_id) })
|
|
||||||
.into(),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
Ok((class_name, DefinitionId(class_def_id), None))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::StmtKind::FunctionDef { name, .. } => {
|
ast::StmtKind::FunctionDef { name, .. } => {
|
||||||
|
@ -278,6 +274,8 @@ impl TopLevelComposer {
|
||||||
// add to the definition list
|
// add to the definition list
|
||||||
self.definition_ast_list.push((
|
self.definition_ast_list.push((
|
||||||
RwLock::new(Self::make_top_level_function_def(
|
RwLock::new(Self::make_top_level_function_def(
|
||||||
|
// TODO: is this fun_name or the above name with mod_path?
|
||||||
|
name.into(),
|
||||||
name.into(),
|
name.into(),
|
||||||
// dummy here, unify with correct type later
|
// dummy here, unify with correct type later
|
||||||
ty_to_be_unified,
|
ty_to_be_unified,
|
||||||
|
@ -801,7 +799,7 @@ impl TopLevelComposer {
|
||||||
resolver,
|
resolver,
|
||||||
type_vars,
|
type_vars,
|
||||||
..
|
..
|
||||||
} = class_def.deref_mut()
|
} = &mut *class_def
|
||||||
{
|
{
|
||||||
if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast {
|
if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast {
|
||||||
(
|
(
|
||||||
|
@ -1161,32 +1159,36 @@ impl TopLevelComposer {
|
||||||
|
|
||||||
/// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function
|
/// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function
|
||||||
fn analyze_function_instance(&mut self) -> Result<(), String> {
|
fn analyze_function_instance(&mut self) -> Result<(), String> {
|
||||||
for (id, (def, ast)) in self.definition_ast_list.iter().enumerate().skip(self.built_in_num) {
|
for (id, (def, ast)) in self.definition_ast_list.iter().enumerate().skip(self.built_in_num)
|
||||||
|
{
|
||||||
let mut function_def = def.write();
|
let mut function_def = def.write();
|
||||||
if let TopLevelDef::Function {
|
if let TopLevelDef::Function { instance_to_stmt, name, simple_name, signature, resolver, .. } =
|
||||||
instance_to_stmt,
|
&mut *function_def
|
||||||
name,
|
|
||||||
signature,
|
|
||||||
var_id,
|
|
||||||
resolver,
|
|
||||||
..
|
|
||||||
} = &mut *function_def
|
|
||||||
{
|
{
|
||||||
if let TypeEnum::TFunc(func_sig) = self.unifier.get_ty(*signature).as_ref() {
|
if let TypeEnum::TFunc(func_sig) = self.unifier.get_ty(*signature).as_ref() {
|
||||||
let FunSignature { args, ret, vars } = &*func_sig.borrow();
|
let FunSignature { args, ret, vars } = &*func_sig.borrow();
|
||||||
// None if is not class method
|
// None if is not class method
|
||||||
let self_type = {
|
let self_type = {
|
||||||
if let Some(class_id) = self.method_class.get(&DefinitionId(id)) {
|
if let Some(class_id) = self.method_class.get(&DefinitionId(id)) {
|
||||||
let class_def = self.definition_ast_list.get(class_id.0).unwrap();
|
let class_def = self.definition_ast_list.get(class_id.0).unwrap();
|
||||||
let class_def = class_def.0.read();
|
let class_def = class_def.0.read();
|
||||||
if let TopLevelDef::Class { type_vars, .. } = &*class_def {
|
if let TopLevelDef::Class { type_vars, constructor, .. } = &*class_def {
|
||||||
let ty_ann = make_self_type_annotation(type_vars, *class_id);
|
let ty_ann = make_self_type_annotation(type_vars, *class_id);
|
||||||
Some(get_type_from_type_annotation_kinds(
|
let self_ty = get_type_from_type_annotation_kinds(
|
||||||
self.extract_def_list().as_slice(),
|
self.extract_def_list().as_slice(),
|
||||||
&mut self.unifier,
|
&mut self.unifier,
|
||||||
&self.primitives_ty,
|
&self.primitives_ty,
|
||||||
&ty_ann,
|
&ty_ann,
|
||||||
)?)
|
)?;
|
||||||
|
if simple_name == "__init__" {
|
||||||
|
let fn_type = self.unifier.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature {
|
||||||
|
args: args.clone(),
|
||||||
|
ret: self_ty,
|
||||||
|
vars: vars.clone()
|
||||||
|
})));
|
||||||
|
self.unifier.unify(fn_type, constructor.unwrap())?;
|
||||||
|
}
|
||||||
|
Some(self_ty)
|
||||||
} else {
|
} else {
|
||||||
unreachable!("must be class def")
|
unreachable!("must be class def")
|
||||||
}
|
}
|
||||||
|
@ -1227,8 +1229,7 @@ impl TopLevelComposer {
|
||||||
let inst_ret = self.unifier.subst(*ret, &subst).unwrap_or(*ret);
|
let inst_ret = self.unifier.subst(*ret, &subst).unwrap_or(*ret);
|
||||||
let inst_args = {
|
let inst_args = {
|
||||||
let unifier = &mut self.unifier;
|
let unifier = &mut self.unifier;
|
||||||
args
|
args.iter()
|
||||||
.iter()
|
|
||||||
.map(|a| FuncArg {
|
.map(|a| FuncArg {
|
||||||
name: a.name.clone(),
|
name: a.name.clone(),
|
||||||
ty: unifier.subst(a.ty, &subst).unwrap_or(a.ty),
|
ty: unifier.subst(a.ty, &subst).unwrap_or(a.ty),
|
||||||
|
@ -1319,15 +1320,15 @@ impl TopLevelComposer {
|
||||||
.sorted()
|
.sorted()
|
||||||
.map(|id| {
|
.map(|id| {
|
||||||
let ty = subst.get(id).unwrap();
|
let ty = subst.get(id).unwrap();
|
||||||
unifier.stringify(*ty, &mut |id| id.to_string(), &mut |id| id.to_string())
|
unifier.stringify(
|
||||||
}).join(", ")
|
*ty,
|
||||||
},
|
&mut |id| id.to_string(),
|
||||||
FunInstance {
|
&mut |id| id.to_string(),
|
||||||
body: fun_body,
|
)
|
||||||
unifier_id: 0,
|
})
|
||||||
calls,
|
.join(", ")
|
||||||
subst,
|
|
||||||
},
|
},
|
||||||
|
FunInstance { body: fun_body, unifier_id: 0, calls, subst },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -50,7 +50,6 @@ impl TopLevelDef {
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
TopLevelDef::Initializer { class_id } => format!("Initializer {{ {:?} }}", class_id),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +93,7 @@ impl TopLevelComposer {
|
||||||
index: usize,
|
index: usize,
|
||||||
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
constructor: Option<Type>
|
||||||
) -> TopLevelDef {
|
) -> TopLevelDef {
|
||||||
TopLevelDef::Class {
|
TopLevelDef::Class {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
@ -102,6 +102,7 @@ impl TopLevelComposer {
|
||||||
fields: Default::default(),
|
fields: Default::default(),
|
||||||
methods: Default::default(),
|
methods: Default::default(),
|
||||||
ancestors: Default::default(),
|
ancestors: Default::default(),
|
||||||
|
constructor,
|
||||||
resolver,
|
resolver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,11 +110,13 @@ impl TopLevelComposer {
|
||||||
/// when first registering, the type is a invalid value
|
/// when first registering, the type is a invalid value
|
||||||
pub fn make_top_level_function_def(
|
pub fn make_top_level_function_def(
|
||||||
name: String,
|
name: String,
|
||||||
|
simple_name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
) -> TopLevelDef {
|
) -> TopLevelDef {
|
||||||
TopLevelDef::Function {
|
TopLevelDef::Function {
|
||||||
name,
|
name,
|
||||||
|
simple_name,
|
||||||
signature: ty,
|
signature: ty,
|
||||||
var_id: Default::default(),
|
var_id: Default::default(),
|
||||||
instance_to_symbol: Default::default(),
|
instance_to_symbol: Default::default(),
|
||||||
|
|
|
@ -53,10 +53,14 @@ pub enum TopLevelDef {
|
||||||
ancestors: Vec<TypeAnnotation>,
|
ancestors: Vec<TypeAnnotation>,
|
||||||
// symbol resolver of the module defined the class, none if it is built-in type
|
// symbol resolver of the module defined the class, none if it is built-in type
|
||||||
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
|
// constructor type
|
||||||
|
constructor: Option<Type>,
|
||||||
},
|
},
|
||||||
Function {
|
Function {
|
||||||
// prefix for symbol, should be unique globally, and not ending with numbers
|
// prefix for symbol, should be unique globally, and not ending with numbers
|
||||||
name: String,
|
name: String,
|
||||||
|
// simple name, the same as in method/function definition
|
||||||
|
simple_name: String,
|
||||||
// function signature.
|
// function signature.
|
||||||
signature: Type,
|
signature: Type,
|
||||||
// instantiated type variable IDs
|
// instantiated type variable IDs
|
||||||
|
@ -75,9 +79,6 @@ pub enum TopLevelDef {
|
||||||
// symbol resolver of the module defined the class
|
// symbol resolver of the module defined the class
|
||||||
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
},
|
},
|
||||||
Initializer {
|
|
||||||
class_id: DefinitionId,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TopLevelContext {
|
pub struct TopLevelContext {
|
||||||
|
|
|
@ -1,64 +1,20 @@
|
||||||
def y_scale(maxX: float, minX: float, height: float, width: float, aspectRatio: float) -> float:
|
class A:
|
||||||
return (maxX-minX)*(height/width)*aspectRatio
|
a: int32
|
||||||
|
def __init__(self, a: int32):
|
||||||
|
self.a = a
|
||||||
|
|
||||||
def check_smaller_than_sixteen(i: int32) -> bool:
|
def get_a(self) -> int32:
|
||||||
return i < 16
|
return self.a
|
||||||
|
|
||||||
def rec(x: int32):
|
def get_self(self) -> A:
|
||||||
if x > 1:
|
return self
|
||||||
output(x)
|
|
||||||
rec(x - 1)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
output(-1)
|
|
||||||
return
|
|
||||||
|
|
||||||
def fib(n: int32) -> int32:
|
|
||||||
if n <= 2:
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
return fib(n - 1) + fib(n - 2)
|
|
||||||
|
|
||||||
def draw():
|
|
||||||
minX = -2.0
|
|
||||||
maxX = 1.0
|
|
||||||
width = 78.0
|
|
||||||
height = 36.0
|
|
||||||
aspectRatio = 2.0
|
|
||||||
|
|
||||||
# test = 1.0 + 1
|
|
||||||
|
|
||||||
yScale = y_scale(maxX, minX, height, width, aspectRatio)
|
|
||||||
|
|
||||||
y = 0.0
|
|
||||||
while y < height:
|
|
||||||
x = 0.0
|
|
||||||
while x < width:
|
|
||||||
c_r = minX+x*(maxX-minX)/width
|
|
||||||
c_i = y*yScale/height-yScale/2.0
|
|
||||||
z_r = c_r
|
|
||||||
z_i = c_i
|
|
||||||
i = 0
|
|
||||||
while check_smaller_than_sixteen(i):
|
|
||||||
if z_r*z_r + z_i*z_i > 4.0:
|
|
||||||
break
|
|
||||||
new_z_r = (z_r*z_r)-(z_i*z_i) + c_r
|
|
||||||
z_i = 2.0*z_r*z_i + c_i
|
|
||||||
z_r = new_z_r
|
|
||||||
i = i + 1
|
|
||||||
output(i)
|
|
||||||
x = x + 1.0
|
|
||||||
output(-1)
|
|
||||||
y = y + 1.0
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def run() -> int32:
|
def run() -> int32:
|
||||||
rec(5)
|
a = A(10)
|
||||||
|
output(a.a)
|
||||||
|
|
||||||
output(fib(10))
|
a = A(20)
|
||||||
output(-1)
|
output(a.a)
|
||||||
|
output(a.get_a())
|
||||||
draw()
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
use std::time::SystemTime;
|
use std::fs;
|
||||||
use std::{collections::HashSet, fs};
|
|
||||||
|
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
passes::{PassManager, PassManagerBuilder},
|
passes::{PassManager, PassManagerBuilder},
|
||||||
targets::*,
|
targets::*,
|
||||||
OptimizationLevel,
|
OptimizationLevel,
|
||||||
};
|
};
|
||||||
use nac3core::typecheck::type_inferencer::PrimitiveStore;
|
use nac3core::typecheck::type_inferencer::PrimitiveStore;
|
||||||
use parking_lot::RwLock;
|
use rustpython_parser::{parser, ast::StmtKind};
|
||||||
use rustpython_parser::parser;
|
|
||||||
use std::{collections::HashMap, path::Path, sync::Arc};
|
use std::{collections::HashMap, path::Path, sync::Arc};
|
||||||
|
|
||||||
use nac3core::{
|
use nac3core::{
|
||||||
|
@ -55,11 +52,17 @@ fn main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
for stmt in parser::parse_program(&program).unwrap().into_iter() {
|
for stmt in parser::parse_program(&program).unwrap().into_iter() {
|
||||||
|
let is_class = matches!(stmt.node, StmtKind::ClassDef{ .. });
|
||||||
let (name, def_id, ty) = composer.register_top_level(
|
let (name, def_id, ty) = composer.register_top_level(
|
||||||
stmt,
|
stmt,
|
||||||
Some(resolver.clone()),
|
Some(resolver.clone()),
|
||||||
"__main__".into(),
|
"__main__".into(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
|
if is_class {
|
||||||
|
internal_resolver.add_id_type(name.clone(), ty.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
internal_resolver.add_id_def(name.clone(), def_id);
|
internal_resolver.add_id_def(name.clone(), def_id);
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
internal_resolver.add_id_type(name, ty);
|
internal_resolver.add_id_type(name, ty);
|
||||||
|
|
Loading…
Reference in New Issue