Compare commits

..

4 Commits

Author SHA1 Message Date
David Mak 6e26c3abb7 artiq: Implement handling for const generic variables 2023-12-08 15:59:47 +08:00
David Mak 3420d8d86c core: Initial implementation for const generics 2023-12-08 15:57:10 +08:00
David Mak 7088a2f3d5 core: Move some SymbolValue functions to symbol_resolver.rs 2023-12-08 15:56:32 +08:00
David Mak c17575199a core: Codegen for ellipsis expression as NotImplemented
A lot of refactoring was performed, specifically with relaxing
expression codegen to return Option in case where ellipsis are used
within a subexpression.
2023-12-08 15:56:32 +08:00
7 changed files with 79 additions and 57 deletions

View File

@ -2,7 +2,7 @@ from inspect import getfullargspec
from functools import wraps
from types import SimpleNamespace
from numpy import int32, int64
from typing import Any, Generic, TypeVar
from typing import Generic, TypeVar
from math import floor, ceil
import nac3artiq
@ -67,11 +67,11 @@ def Some(v: T) -> Option[T]:
none = Option(None)
class _ConstGenericDummy:
class _ConstGenericMarker:
pass
def ConstGeneric(name, constraint):
return TypeVar(name, _ConstGenericDummy, constraint)
return TypeVar(name, _ConstGenericMarker, constraint)
def round64(x):
return round(x)

View File

@ -26,7 +26,7 @@ pub struct Location {
impl fmt::Display for Location {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}:{}", self.file.0, self.row, self.column)
write!(f, "{}: line {} column {}", self.file.0, self.row, self.column)
}
}

View File

@ -22,7 +22,7 @@ use inkwell::{
IntPredicate
};
type BuiltinInfo = Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>;
type BuiltinInfo = (Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>, &'static [&'static str]);
pub fn get_exn_constructor(
name: &str,
@ -1906,6 +1906,68 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let ast_list: Vec<Option<ast::Stmt<()>>> =
(0..top_level_def_list.len()).map(|_| None).collect();
izip!(top_level_def_list, ast_list).collect_vec()
(
izip!(top_level_def_list, ast_list).collect_vec(),
&[
"int32",
"int64",
"uint32",
"uint64",
"float",
"round",
"round64",
"np_round",
"range",
"str",
"bool",
"floor",
"floor64",
"np_floor",
"ceil",
"ceil64",
"np_ceil",
"len",
"min",
"max",
"abs",
"np_isnan",
"np_isinf",
"np_sin",
"np_cos",
"np_exp",
"np_exp2",
"np_log",
"np_log10",
"np_log2",
"np_fabs",
"np_sqrt",
"np_rint",
"np_tan",
"np_arcsin",
"np_arccos",
"np_arctan",
"np_sinh",
"np_cosh",
"np_tanh",
"np_arcsinh",
"np_arccosh",
"np_arctanh",
"np_expm1",
"np_cbrt",
"sp_spec_erf",
"sp_spec_erfc",
"sp_spec_gamma",
"sp_spec_gammaln",
"sp_spec_j0",
"sp_spec_j1",
"np_arctan2",
"np_copysign",
"np_fmax",
"np_fmin",
"np_ldexp",
"np_hypot",
"np_nextafter",
"Some",
],
)
}

View File

@ -53,7 +53,7 @@ impl TopLevelComposer {
core_config: ComposerConfig,
) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) {
let mut primitives = Self::make_primitives();
let mut definition_ast_list = builtins::get_builtins(&mut primitives);
let (mut definition_ast_list, builtin_name_list) = builtins::get_builtins(&mut primitives);
let primitives_ty = primitives.0;
let mut unifier = primitives.1;
let mut keyword_list: HashSet<StrRef> = HashSet::from_iter(vec![
@ -83,26 +83,12 @@ impl TopLevelComposer {
let mut builtin_id: HashMap<StrRef, DefinitionId> = Default::default();
let mut builtin_ty: HashMap<StrRef, Type> = Default::default();
let builtin_name_list = definition_ast_list.iter()
.map(|def_ast| match *def_ast.0.read() {
TopLevelDef::Class { name, .. } => name.to_string(),
TopLevelDef::Function { simple_name, .. } => simple_name.to_string(),
})
.collect_vec();
for (id, name) in builtin_name_list.iter().enumerate() {
for (id, name) in builtin_name_list.iter().rev().enumerate() {
let name = (**name).into();
let id = definition_ast_list.len() - id - 1;
let def = definition_ast_list[id].0.read();
if let TopLevelDef::Function { name: func_name, simple_name, signature, .. } = &*def {
assert_eq!(name, *simple_name, "Simple name of builtin function should match builtin name list");
// Do not add member functions into the list of builtin IDs;
// Here we assume that all builtin top-level functions have the same name and simple
// name, and all member functions have something prefixed to its name
if *func_name != simple_name.to_string() {
continue
}
if let TopLevelDef::Function { simple_name, signature, .. } = &*def {
assert!(name == *simple_name);
builtin_ty.insert(name, *signature);
builtin_id.insert(name, DefinitionId(id));
} else if let TopLevelDef::Class { name, constructor, object_id, .. } = &*def

View File

@ -361,7 +361,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
pass
"}
],
vec!["application of type vars to generic class is not currently supported (at unknown:4:24)"];
vec!["application of type vars to generic class is not currently supported (at unknown: line 4 column 24)"];
"err no type var in generic app"
)]
#[test_case(
@ -417,7 +417,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
def __init__():
pass
"}],
vec!["__init__ method must have a `self` parameter (at unknown:2:5)"];
vec!["__init__ method must have a `self` parameter (at unknown: line 2 column 5)"];
"err no self_1"
)]
#[test_case(
@ -439,7 +439,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
"}
],
vec!["a class definition can only have at most one base class declaration and one generic declaration (at unknown:1:24)"];
vec!["a class definition can only have at most one base class declaration and one generic declaration (at unknown: line 1 column 24)"];
"err multiple inheritance"
)]
#[test_case(
@ -507,7 +507,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
pass
"}
],
vec!["duplicate definition of class `A` (at unknown:1:1)"];
vec!["duplicate definition of class `A` (at unknown: line 1 column 1)"];
"class same name"
)]
fn test_analyze(source: Vec<&str>, res: Vec<&str>) {

View File

@ -146,7 +146,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
slice: &ast::Expr<T>,
unifier: &mut Unifier,
mut locked: HashMap<DefinitionId, Vec<Type>>| {
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into(), "Option".into()].contains(id)
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into()].contains(id)
{
return Err(format!("keywords cannot be class name (at {})", expr.location));
}

View File

@ -1,26 +0,0 @@
def run() -> int32:
# Numeric Primitives
b: bool = False
i32: int32 = 0
i64: int64 = int64(0)
u32: uint32 = uint32(0)
u64: uint64 = uint64(0)
f64: float = 0.0
# String
s: str = ""
# List
l_i32: list[int32] = []
l_f64: list[float] = []
l_str: list[str] = []
# Option
o_some: Option[int32] = Some(0)
o_none: Option[int32] = none
# Tuple
t_i32_i32: tuple[int32, int32] = (0, 0)
t_i32_f64: tuple[int32, float] = (0, 0.0)
return 0