Kernel only attribute annotation (#76) #127

Merged
sb10q merged 8 commits from kernel_only_annotation into master 2021-12-19 11:04:53 +08:00
4 changed files with 46 additions and 26 deletions
Showing only changes of commit bd97f89514 - Show all commits

View File

@ -9,7 +9,7 @@ import nac3artiq
__all__ = [ __all__ = [
"KernelInvariant", "virtual", "Kernel", "KernelInvariant", "virtual",
"round64", "floor64", "ceil64", "round64", "floor64", "ceil64",
"extern", "kernel", "portable", "nac3", "extern", "kernel", "portable", "nac3",
"ms", "us", "ns", "ms", "us", "ns",
@ -21,6 +21,9 @@ __all__ = [
T = TypeVar('T') T = TypeVar('T')
class Kernel(Generic[T]):
pass
class KernelInvariant(Generic[T]): class KernelInvariant(Generic[T]):
pass pass

View File

@ -22,7 +22,7 @@ use parking_lot::{Mutex, RwLock};
use nac3core::{ use nac3core::{
codegen::{concrete_type::ConcreteTypeStore, CodeGenTask, WithCall, WorkerRegistry}, codegen::{concrete_type::ConcreteTypeStore, CodeGenTask, WithCall, WorkerRegistry},
symbol_resolver::SymbolResolver, symbol_resolver::SymbolResolver,
toplevel::{composer::TopLevelComposer, DefinitionId, GenCall, TopLevelDef}, toplevel::{composer::{TopLevelComposer, CoreMode}, DefinitionId, GenCall, TopLevelDef},
typecheck::typedef::{FunSignature, FuncArg}, typecheck::typedef::{FunSignature, FuncArg},
typecheck::{type_inferencer::PrimitiveStore, typedef::Type}, typecheck::{type_inferencer::PrimitiveStore, typedef::Type},
}; };
@ -239,7 +239,7 @@ impl Nac3 {
}))), }))),
), ),
]; ];
let (_, builtins_def, builtins_ty) = TopLevelComposer::new(builtins.clone()); let (_, builtins_def, builtins_ty) = TopLevelComposer::new(builtins.clone(), CoreMode::Artiq);
let builtins_mod = PyModule::import(py, "builtins").unwrap(); let builtins_mod = PyModule::import(py, "builtins").unwrap();
let id_fn = builtins_mod.getattr("id").unwrap(); let id_fn = builtins_mod.getattr("id").unwrap();
Review

duplication - see comment below

duplication - see comment below
@ -375,7 +375,7 @@ impl Nac3 {
filename: &str, filename: &str,
py: Python, py: Python,
) -> PyResult<()> { ) -> PyResult<()> {
let (mut composer, _, _) = TopLevelComposer::new(self.builtins.clone()); let (mut composer, _, _) = TopLevelComposer::new(self.builtins.clone(), CoreMode::Artiq);
let mut id_to_def = HashMap::new(); let mut id_to_def = HashMap::new();
let mut id_to_type = HashMap::new(); let mut id_to_type = HashMap::new();

View File

@ -9,6 +9,11 @@ use crate::{
use super::*; use super::*;
pub enum CoreMode {
Outdated
Review

Just make the names configurable.

Just make the names configurable.
Artiq,
Standalone
}
type DefAst = (Arc<RwLock<TopLevelDef>>, Option<ast::Stmt<()>>); type DefAst = (Arc<RwLock<TopLevelDef>>, Option<ast::Stmt<()>>);
pub struct TopLevelComposer { pub struct TopLevelComposer {
// list of top level definitions, same as top level context // list of top level definitions, same as top level context
@ -25,11 +30,13 @@ pub struct TopLevelComposer {
pub method_class: HashMap<DefinitionId, DefinitionId>, pub method_class: HashMap<DefinitionId, DefinitionId>,
// number of built-in function and classes in the definition list, later skip // number of built-in function and classes in the definition list, later skip
pub builtin_num: usize, pub builtin_num: usize,
// indicate the mode that we are using the core
Outdated
Review

Misleading comment. I suggest removing it, since it's fairly obvious what this does from the code already.

Misleading comment. I suggest removing it, since it's fairly obvious what this does from the code already.
pub mode: CoreMode,
Outdated
Review

Replace with something like:

pub kernel_ann: Option<str>,
pub kernel_invariant_ann: str
Replace with something like: ``` pub kernel_ann: Option<str>, pub kernel_invariant_ann: str ```
Outdated
Review

And they could default to non-ARTIQ None / "Invariant".

And they could default to non-ARTIQ ``None / "Invariant"``.
} }
impl Default for TopLevelComposer { impl Default for TopLevelComposer {
fn default() -> Self { fn default() -> Self {
Self::new(vec![]).0 Self::new(vec![], CoreMode::Standalone).0
} }
} }
@ -38,6 +45,7 @@ impl TopLevelComposer {
/// 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( pub fn new(
builtins: Vec<(StrRef, FunSignature, Arc<GenCall>)>, builtins: Vec<(StrRef, FunSignature, Arc<GenCall>)>,
mode: CoreMode
) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) { ) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) {
let mut primitives = Self::make_primitives(); let mut primitives = Self::make_primitives();
let (mut definition_ast_list, builtin_name_list) = builtins::get_builtins(&mut primitives); let (mut definition_ast_list, builtin_name_list) = builtins::get_builtins(&mut primitives);
@ -108,6 +116,7 @@ impl TopLevelComposer {
keyword_list, keyword_list,
defined_names, defined_names,
method_class, method_class,
mode
}, },
builtin_id, builtin_id,
builtin_ty, builtin_ty,
@ -554,7 +563,7 @@ impl TopLevelComposer {
unifier, unifier,
primitives, primitives,
&mut type_var_to_concrete_def, &mut type_var_to_concrete_def,
&self.keyword_list, (&self.keyword_list, &self.mode)
)? )?
} }
} }
@ -827,8 +836,9 @@ impl TopLevelComposer {
unifier: &mut Unifier, unifier: &mut Unifier,
primitives: &PrimitiveStore, primitives: &PrimitiveStore,
type_var_to_concrete_def: &mut HashMap<Type, TypeAnnotation>, type_var_to_concrete_def: &mut HashMap<Type, TypeAnnotation>,
keyword_list: &HashSet<StrRef>, core_info: (&HashSet<StrRef>, &CoreMode),
) -> Result<(), String> { ) -> Result<(), String> {
let (keyword_list, core_mode) = core_info;
let mut class_def = class_def.write(); let mut class_def = class_def.write();
let ( let (
class_id, class_id,
@ -1059,19 +1069,26 @@ impl TopLevelComposer {
Outdated
Review

This is too restrictive. The restriction is worse than the possibility of bugs from the user mutating the list unexpectedly.

This is too restrictive. The restriction is worse than the possibility of bugs from the user mutating the list unexpectedly.
// handle Kernel[T], KernelInvariant[T] // handle Kernel[T], KernelInvariant[T]
let (annotation, mutable) = { let (annotation, mutable) = {
let mut result = None; match core_mode {
if let ast::ExprKind::Subscript { value, slice, .. } = &annotation.as_ref().node { CoreMode::Artiq => match &annotation.as_ref().node {
if let ast::ExprKind::Name { id, .. } = &value.node { ast::ExprKind::Subscript { value, slice, .. } if matches!(
result = if id == &"Kernel".into() { &value.node,
Some((slice, true)) ast::ExprKind::Name { id, .. } if id == &"Kernel".into()
} else if id == &"KernelInvariant".into() { ) => (slice, true),
Some((slice, false)) ast::ExprKind::Subscript { value, slice, .. } if matches!(
} else { &value.node,
Outdated
Review

As before, please remove debug prints.
This is also not an error, if it is not annotated with Kernel or KernelInvariant it is simply a host-only attribute.

As before, please remove debug prints. This is also not an error, if it is not annotated with ``Kernel`` or ``KernelInvariant`` it is simply a host-only attribute.
None ast::ExprKind::Name { id, .. } if id == &"KernelInvariant".into()
} ) => (slice, false),
_ => continue // ignore fields annotated otherwise
},
CoreMode::Standalone => match &annotation.as_ref().node {
ast::ExprKind::Subscript { value, slice, .. } if matches!(
&value.node,
ast::ExprKind::Name { id, .. } if id == &"Invariant".into()
) => (slice, false),
_ => (annotation, true)
} }
} }
result.unwrap_or((annotation, true))
}; };
class_fields_def.push((*attr, dummy_field_type, mutable)); class_fields_def.push((*attr, dummy_field_type, mutable));

View File

@ -3,13 +3,10 @@ use inkwell::{
targets::*, targets::*,
OptimizationLevel, OptimizationLevel,
}; };
use nac3core::typecheck::{type_inferencer::PrimitiveStore, typedef::{Type, Unifier}}; use std::{borrow::Borrow, collections::HashMap, env, fs, path::Path, sync::Arc, time::SystemTime};
use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser};
use parking_lot::RwLock; use parking_lot::RwLock;
use std::{borrow::Borrow, env};
use std::fs;
use std::{collections::HashMap, path::Path, sync::Arc, time::SystemTime};
use nac3parser::{ast::{Expr, ExprKind, StmtKind}, parser};
use nac3core::{ use nac3core::{
codegen::{ codegen::{
concrete_type::ConcreteTypeStore, CodeGenTask, DefaultCodeGenerator, WithCall, concrete_type::ConcreteTypeStore, CodeGenTask, DefaultCodeGenerator, WithCall,
@ -17,11 +14,11 @@ use nac3core::{
}, },
symbol_resolver::SymbolResolver, symbol_resolver::SymbolResolver,
toplevel::{ toplevel::{
composer::TopLevelComposer, composer::{TopLevelComposer, CoreMode},
TopLevelDef, helper::parse_parameter_default_value, TopLevelDef, helper::parse_parameter_default_value,
type_annotation::*, type_annotation::*,
}, },
typecheck::typedef::FunSignature, typecheck::{type_inferencer::PrimitiveStore, typedef::{Type, Unifier, FunSignature}}
}; };
mod basic_symbol_resolver; mod basic_symbol_resolver;
@ -47,7 +44,10 @@ fn main() {
}; };
let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0; let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0;
let (mut composer, builtins_def, builtins_ty) = TopLevelComposer::new(vec![]); let (mut composer, builtins_def, builtins_ty) = TopLevelComposer::new(
vec![],
CoreMode::Standalone
Outdated
Review

You implemented Default already - don't repeat yourself?

You implemented ``Default`` already - don't repeat yourself?
);
let internal_resolver: Arc<ResolverInternal> = ResolverInternal { let internal_resolver: Arc<ResolverInternal> = ResolverInternal {
id_to_type: builtins_ty.into(), id_to_type: builtins_ty.into(),