master #311

Closed
Aadityavardhan wants to merge 8 commits from (deleted):master into master
133 changed files with 49 additions and 6 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
Cargo.lock generated Normal file → Executable file
View File

0
Cargo.toml Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
flake.lock Normal file → Executable file
View File

0
flake.nix Normal file → Executable file
View File

0
nac3.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

0
nac3artiq/Cargo.toml Normal file → Executable file
View File

0
nac3artiq/demo/demo.py Normal file → Executable file
View File

0
nac3artiq/demo/device_db.py Normal file → Executable file
View File

0
nac3artiq/demo/embedding_map.py Normal file → Executable file
View File

0
nac3artiq/demo/min_artiq.py Normal file → Executable file
View File

0
nac3artiq/src/codegen.rs Normal file → Executable file
View File

0
nac3artiq/src/kernel.ld Normal file → Executable file
View File

0
nac3artiq/src/lib.rs Normal file → Executable file
View File

0
nac3artiq/src/symbol_resolver.rs Normal file → Executable file
View File

0
nac3artiq/src/timeline.rs Normal file → Executable file
View File

0
nac3ast/Cargo.toml Normal file → Executable file
View File

0
nac3ast/Python.asdl Normal file → Executable file
View File

0
nac3ast/asdl.py Normal file → Executable file
View File

0
nac3ast/src/ast_gen.rs Normal file → Executable file
View File

0
nac3ast/src/constant.rs Normal file → Executable file
View File

0
nac3ast/src/fold_helpers.rs Normal file → Executable file
View File

0
nac3ast/src/impls.rs Normal file → Executable file
View File

0
nac3ast/src/lib.rs Normal file → Executable file
View File

0
nac3ast/src/location.rs Normal file → Executable file
View File

0
nac3core/Cargo.toml Normal file → Executable file
View File

0
nac3core/build.rs Normal file → Executable file
View File

0
nac3core/src/codegen/concrete_type.rs Normal file → Executable file
View File

0
nac3core/src/codegen/expr.rs Normal file → Executable file
View File

0
nac3core/src/codegen/generator.rs Normal file → Executable file
View File

0
nac3core/src/codegen/irrt/irrt.c Normal file → Executable file
View File

0
nac3core/src/codegen/irrt/mod.rs Normal file → Executable file
View File

0
nac3core/src/codegen/mod.rs Normal file → Executable file
View File

0
nac3core/src/codegen/stmt.rs Normal file → Executable file
View File

0
nac3core/src/codegen/test.rs Normal file → Executable file
View File

0
nac3core/src/lib.rs Normal file → Executable file
View File

0
nac3core/src/symbol_resolver.rs Normal file → Executable file
View File

3
nac3core/src/toplevel/builtins.rs Normal file → Executable file
View File

@ -74,6 +74,7 @@ pub fn get_exn_constructor(
constructor: Some(signature), constructor: Some(signature),
resolver: None, resolver: None,
loc: None, loc: None,
static_fields: Default::default(),
}; };
(fun_def, class_def, signature, exn_type) (fun_def, class_def, signature, exn_type)
} }
@ -175,6 +176,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
type_vars: Default::default(), type_vars: Default::default(),
fields: exception_fields, fields: exception_fields,
methods: Default::default(), methods: Default::default(),
static_fields: Default::default(),
ancestors: vec![], ancestors: vec![],
constructor: None, constructor: None,
resolver: None, resolver: None,
@ -200,6 +202,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
object_id: DefinitionId(10), object_id: DefinitionId(10),
type_vars: vec![option_ty_var], type_vars: vec![option_ty_var],
fields: vec![], fields: vec![],
static_fields: vec![],
methods: vec![ methods: vec![
("is_some".into(), is_some_ty.0, DefinitionId(11)), ("is_some".into(), is_some_ty.0, DefinitionId(11)),
("is_none".into(), is_some_ty.0, DefinitionId(12)), ("is_none".into(), is_some_ty.0, DefinitionId(12)),

49
nac3core/src/toplevel/composer.rs Normal file → Executable file
View File

@ -1040,6 +1040,7 @@ impl TopLevelComposer {
class_body_ast, class_body_ast,
_class_ancestor_def, _class_ancestor_def,
class_fields_def, class_fields_def,
class_static_fields_def, // Introduce static class attribute list into the function
class_methods_def, class_methods_def,
class_type_vars_def, class_type_vars_def,
class_resolver, class_resolver,
@ -1047,6 +1048,7 @@ impl TopLevelComposer {
object_id, object_id,
ancestors, ancestors,
fields, fields,
static_fields,
methods, methods,
resolver, resolver,
type_vars, type_vars,
@ -1054,7 +1056,7 @@ impl TopLevelComposer {
} = &mut *class_def } = &mut *class_def
{ {
if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast { if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast {
(*object_id, *name, bases, body, ancestors, fields, methods, type_vars, resolver) (*object_id, *name, bases, body, ancestors, fields, static_fields, methods, type_vars, resolver)
} else { } else {
unreachable!("here must be class def ast"); unreachable!("here must be class def ast");
} }
@ -1268,7 +1270,8 @@ impl TopLevelComposer {
.unify(method_dummy_ty, method_type) .unify(method_dummy_ty, method_type)
.map_err(|e| e.to_display(unifier).to_string())?; .map_err(|e| e.to_display(unifier).to_string())?;
} }
ast::StmtKind::AnnAssign { target, annotation, value: None, .. } => { // Reset value from none since fields in the form "ATTR_0: int32 = 10" need to be initialised
ast::StmtKind::AnnAssign { target, annotation, value, .. } => {
if let ast::ExprKind::Name { id: attr, .. } = &target.node { if let ast::ExprKind::Name { id: attr, .. } = &target.node {
if defined_fields.insert(attr.to_string()) { if defined_fields.insert(attr.to_string()) {
let dummy_field_type = unifier.get_dummy_var().0; let dummy_field_type = unifier.get_dummy_var().0;
@ -1294,6 +1297,10 @@ impl TopLevelComposer {
_ if core_config.kernel_ann.is_none() => (annotation, true), _ if core_config.kernel_ann.is_none() => (annotation, true),
_ => continue, // ignore fields annotated otherwise _ => continue, // ignore fields annotated otherwise
}; };
// If the value node is provided, then it must be a static class attribute
if let Option::Some(..) = &value{
class_static_fields_def.push((*attr, dummy_field_type, mutable));
}
class_fields_def.push((*attr, dummy_field_type, mutable)); class_fields_def.push((*attr, dummy_field_type, mutable));
let parsed_annotation = parse_ast_to_type_annotation_kinds( let parsed_annotation = parse_ast_to_type_annotation_kinds(
@ -1335,7 +1342,34 @@ impl TopLevelComposer {
)); ));
} }
} }
ast::StmtKind::Assign { .. } => {}, // we don't class attributes
// Add assign branch since fields in the form "ATTR_0 = 5" in the class body qualify as static class attributes
// However, type checking and expression folding needs to be performed in order to correctly
// Infer the type of target
ast::StmtKind::Assign { targets, value, .. } => {
for target in targets {
if let ast::ExprKind::Name { id: attr, .. } = &target.node {
if defined_fields.insert(attr.to_string()) {
let dummy_field_type = unifier.get_dummy_var().0;
class_static_fields_def.push((*attr, dummy_field_type, true));
class_fields_def.push((*attr, dummy_field_type, true));
} else {
return Err(format!(
"same class fields `{}` defined twice (at {})",
attr, target.location
));
}
} else {
return Err(format!(
"unsupported statement type in class definition body (at {})",
target.location
));
}
}
},
ast::StmtKind::Pass { .. } => {} ast::StmtKind::Pass { .. } => {}
ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior
_ => { _ => {
@ -1516,6 +1550,7 @@ impl TopLevelComposer {
ancestors, ancestors,
methods, methods,
fields, fields,
static_fields, // Introduce static fields for (un)initialization check
type_vars, type_vars,
name: class_name, name: class_name,
object_id, object_id,
@ -1618,11 +1653,13 @@ impl TopLevelComposer {
unreachable!("must be init function here") unreachable!("must be init function here")
} }
let all_inited = Self::get_all_assigned_field(body.as_slice())?; let all_inited = Self::get_all_assigned_field(body.as_slice())?;
for (f, _, _) in fields { // If a field is uninitialized but also a static class attribute, don't
if !all_inited.contains(f) { // throw an error due to uninitialization
for f in fields {
if !all_inited.contains(&f.0) && !static_fields.contains(&f) {
return Err(format!( return Err(format!(
"fields `{}` of class `{}` not fully initialized in the initializer (at {})", "fields `{}` of class `{}` not fully initialized in the initializer (at {})",
f, &f.0,
class_name, class_name,
body[0].location, body[0].location,
)); ));

1
nac3core/src/toplevel/helper.rs Normal file → Executable file
View File

@ -162,6 +162,7 @@ impl TopLevelComposer {
object_id: DefinitionId(index), object_id: DefinitionId(index),
type_vars: Default::default(), type_vars: Default::default(),
fields: Default::default(), fields: Default::default(),
static_fields: Default::default(), // Initialize for constructor
methods: Default::default(), methods: Default::default(),
ancestors: Default::default(), ancestors: Default::default(),
constructor, constructor,

2
nac3core/src/toplevel/mod.rs Normal file → Executable file
View File

@ -92,6 +92,8 @@ pub enum TopLevelDef {
// name, type, is mutable // name, type, is mutable
fields: Vec<(StrRef, Type, bool)>, fields: Vec<(StrRef, Type, bool)>,
// class methods, pointing to the corresponding function definition. // class methods, pointing to the corresponding function definition.
static_fields: Vec<(StrRef, Type, bool)>,
// list of static data members
methods: Vec<(StrRef, Type, DefinitionId)>, methods: Vec<(StrRef, Type, DefinitionId)>,
// ancestor classes, including itself. // ancestor classes, including itself.
ancestors: Vec<TypeAnnotation>, ancestors: Vec<TypeAnnotation>,

0
nac3core/src/toplevel/test.rs Normal file → Executable file
View File

0
nac3core/src/toplevel/type_annotation.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/function_check.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/magic_methods.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/mod.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/type_error.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/type_inferencer/mod.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/type_inferencer/test.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/typedef/mod.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/typedef/test.rs Normal file → Executable file
View File

0
nac3core/src/typecheck/unification_table.rs Normal file → Executable file
View File

0
nac3ld/Cargo.toml Normal file → Executable file
View File

0
nac3ld/src/dwarf.rs Normal file → Executable file
View File

0
nac3ld/src/elf.rs Normal file → Executable file
View File

0
nac3ld/src/lib.rs Normal file → Executable file
View File

0
nac3parser/Cargo.toml Normal file → Executable file
View File

0
nac3parser/README.md Normal file → Executable file
View File

0
nac3parser/build.rs Normal file → Executable file
View File

0
nac3parser/src/config_comment_helper.rs Normal file → Executable file
View File

0
nac3parser/src/error.rs Normal file → Executable file
View File

0
nac3parser/src/fstring.rs Normal file → Executable file
View File

0
nac3parser/src/function.rs Normal file → Executable file
View File

0
nac3parser/src/lexer.rs Normal file → Executable file
View File

0
nac3parser/src/lib.rs Normal file → Executable file
View File

0
nac3parser/src/mode.rs Normal file → Executable file
View File

0
nac3parser/src/parser.rs Normal file → Executable file
View File

0
nac3parser/src/python.lalrpop Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

View File

Some files were not shown because too many files have changed in this diff Show More