Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support array.len #262

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/circuit_writer/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl Var {
}

/// Same as [crate::var::VarInfo], but with Term based Var.
#[derive(Debug)]
pub enum VarOrRef {
Var(Var),

Expand Down Expand Up @@ -376,6 +377,7 @@ pub(crate) struct IRWriter<B: Backend> {
impl<B: Backend> IRWriter<B> {
/// Same as circuit_writer::compile_stmt
fn compile_stmt(&mut self, fn_env: &mut FnEnv, stmt: &Stmt) -> Result<Option<VarOrRef>> {
dbg!("compile_stmt");
match &stmt.kind {
StmtKind::Assign { mutable, lhs, rhs } => {
// compute the rhs
Expand Down Expand Up @@ -612,6 +614,7 @@ impl<B: Backend> IRWriter<B> {
args,
..
} => {
dbg!("impl IrWriter compute_expr");
// sanity check
if fn_name.value == "main" {
Err(self.error(ErrorKind::RecursiveMain, expr.span))?
Expand Down Expand Up @@ -1017,6 +1020,41 @@ impl<B: Backend> IRWriter<B> {
Ok(Some(var))
}

// TODO fix a duplicated code
ExprKind::ArrayLen { array } => {
// retrieve var of array
let var = self
.compute_expr(fn_env, array)?
.expect("array access on non-array");

// retrieve the type of the elements in the array
let array_typ = self.expr_type(array).expect("cannot find type of array");

let len = match array_typ {
TyKind::Array(_, array_len) => *array_len as usize,
_ => Err(Error::new(
"compute-expr",
ErrorKind::UnexpectedError("expected array"),
expr.span,
))?,
};

let start = len;

// out-of-bound checks
if start >= var.len() || start + len > var.len() {
return Err(self.error(
ErrorKind::ArrayIndexOutOfBounds(start, var.len()),
expr.span,
));
}

let var = var.narrow(start, len);
println!("impl IRWriter, compute_expr, ArrayLen, var: {:?}", var);

Ok(Some(var))
}

ExprKind::ArrayDeclaration(items) => {
let mut cvars = vec![];

Expand Down
37 changes: 37 additions & 0 deletions src/circuit_writer/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl<B: Backend> CircuitWriter<B> {
fn_env: &mut FnEnv<B::Field, B::Var>,
stmt: &Stmt,
) -> Result<Option<VarOrRef<B>>> {
dbg!("compile_stmt");
match &stmt.kind {
StmtKind::Assign { mutable, lhs, rhs } => {
// compute the rhs
Expand Down Expand Up @@ -385,6 +386,7 @@ impl<B: Backend> CircuitWriter<B> {
args,
..
} => {
println!("impl CircuitWriter compute_expr");
// sanity check
if fn_name.value == "main" {
Err(self.error(ErrorKind::RecursiveMain, expr.span))?
Expand Down Expand Up @@ -425,6 +427,7 @@ impl<B: Backend> CircuitWriter<B> {
match &fn_info.kind {
// assert() <-- for example
FnKind::BuiltIn(sig, handle, _) => {
dbg!("compute_expr, FnKind::BuiltIn");
let res = handle(self, &sig.generics, &vars, expr.span);
res.map(|r| r.map(VarOrRef::Var))
}
Expand Down Expand Up @@ -775,6 +778,40 @@ impl<B: Backend> CircuitWriter<B> {
Ok(Some(var))
}

// TODO declare a function, fix duplicated code
ExprKind::ArrayLen { array } => {
// retrieve var of array
let var = self
.compute_expr(fn_env, array)?
.expect("array access on non-array");

// retrieve the type of the elements in the array
let array_typ = self.expr_type(array).expect("cannot find type of array");

let len = match array_typ {
TyKind::Array(_, array_len) => *array_len as usize,
_ => Err(Error::new(
"compute-expr",
ErrorKind::UnexpectedError("expected array"),
expr.span,
))?,
};

let start = len;

// out-of-bound checks
if start >= var.len() || start + len > var.len() {
return Err(self.error(
ErrorKind::ArrayIndexOutOfBounds(start, var.len()),
expr.span,
));
}

let var = var.narrow(start, len);

Ok(Some(var))
}

ExprKind::ArrayDeclaration(items) => {
let mut cvars = vec![];

Expand Down
25 changes: 21 additions & 4 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub fn typecheck_next_file_inner<B: Backend>(
node_id: usize,
server_mode: &mut Option<crate::server::ServerShim>,
) -> Result<usize> {
dbg!("typecheck_next_file_inner");
let is_lib = this_module.is_some();

// parsing to name resolution
Expand Down Expand Up @@ -149,6 +150,7 @@ pub fn get_nast<B: Backend>(
node_id: usize,
server_mode: &mut Option<crate::server::ServerShim>,
) -> Result<(NAST<B>, usize)> {
dbg!("nast_pass");
// save filename and source code
let filename_id = sources.add(filename.clone(), code);
let code = &sources.map[&filename_id].1;
Expand All @@ -166,6 +168,8 @@ pub fn get_nast<B: Backend>(
println!("lexer succeeded");
}

dbg!("nast_pass, lexer succeeded ");

// debug server
if let Some(server_mode) = server_mode {
server_mode.send(
Expand All @@ -176,14 +180,27 @@ pub fn get_nast<B: Backend>(
let _ = server_mode.recv();
}

dbg!("nast_pass, debug server succeeded ");
println!("tokens: {:?}", tokens);

// parser
let (ast, new_node_id) = AST::parse(filename_id, tokens, node_id)?;
if std::env::var("NONAME_VERBOSE").is_ok() {
println!("parser succeeded");
}
// let (ast, new_node_id) = AST::parse(filename_id, tokens, node_id)?;
// if std::env::var("NONAME_VERBOSE").is_ok() {
// println!("parser succeeded");
// }
let (ast, new_node_id) = match AST::parse(filename_id, tokens, node_id) {
Ok((ast, new_node_id)) => (ast, new_node_id),
Err(err) => {
println!("AST::parse Error occurred: {}", err);
return Err(err);
}
};

dbg!("nast_pass, AST::parse succeeded ");

// debug server
if let Some(server_mode) = server_mode {
dbg!(" if let Some(server_mode) = server_mode {");
server_mode.send(format!("ast of {filename}"), &ast);
// block on an answer
let _ = server_mode.recv();
Expand Down
22 changes: 22 additions & 0 deletions src/mast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,14 @@ impl<B: Backend> FnInfo<B> {
observed_args: &[ExprMonoInfo],
ctx: &mut MastCtx<B>,
) -> Result<FnSig> {
dbg!("resolve_generic_signature");
match self.kind {
FnKind::BuiltIn(ref mut sig, _, _) => {
println!("resolve_generic_signature, FnKind::BuiltIn, sig: {:?}", sig);
sig.resolve_generic_values(observed_args, ctx)?;
}
FnKind::Native(ref mut func) => {
println!("resolve_generic_signature, FnKind::Native, func: {:?}", func);
func.sig.resolve_generic_values(observed_args, ctx)?;
}
};
Expand Down Expand Up @@ -430,6 +433,7 @@ impl<B: Backend> Mast<B> {

/// Returns the function info by fully qualified name.
pub fn fn_info(&self, qualified: &FullyQualified) -> Option<&FnInfo<B>> {
dbg!("imple Mast fn_info");
self.0.fn_info(qualified)
}

Expand Down Expand Up @@ -464,6 +468,7 @@ impl<B: Backend> Mast<B> {
/// This is the entry point of the monomorphization process.
/// It stores the monomorphized AST at the end.
pub fn monomorphize<B: Backend>(tast: TypeChecker<B>) -> Result<Mast<B>> {
println!("monomorphize");
let mut ctx = MastCtx::new(tast);

let qualified = FullyQualified::local("main".to_string());
Expand Down Expand Up @@ -575,6 +580,8 @@ fn monomorphize_expr<B: Backend>(
args,
unsafe_attr,
} => {
dbg!("monomorphize_expr");
println!("fn_name: {:?}", fn_name);
// compute the observed arguments types
let mut observed = Vec::with_capacity(args.len());
for arg in args {
Expand Down Expand Up @@ -651,8 +658,10 @@ fn monomorphize_expr<B: Backend>(
method_name,
args,
} => {
dbg!("expr_mono");
// retrieve struct name on the lhs
let lhs_mono = monomorphize_expr(ctx, lhs, mono_fn_env)?;
println!("lhs_mono: {:?}", lhs_mono);
let (module, struct_name) = match lhs_mono.clone().typ {
Some(TyKind::Custom { module, name }) => (module, name),
_ => return Err(error(ErrorKind::MethodCallOnNonCustomStruct, expr.span)),
Expand Down Expand Up @@ -959,6 +968,19 @@ fn monomorphize_expr<B: Backend>(
ExprMonoInfo::new(mexpr, el_typ, None)
}

ExprKind::ArrayLen { array } => {
let array_mono = monomorphize_expr(ctx, array, mono_fn_env)?;

let mexpr = expr.to_mast(
ctx,
&ExprKind::ArrayLen {
array: Box::new(array_mono.expr),
},
);

ExprMonoInfo::new(mexpr, array_mono.typ, None)
}

ExprKind::ArrayDeclaration(items) => {
let len: u32 = items.len().try_into().expect("array too large");

Expand Down
19 changes: 18 additions & 1 deletion src/name_resolution/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,18 @@ impl NameResCtx {
}
ExprKind::MethodCall {
lhs,
method_name: _,
method_name,
args,
} => {
println!("resolve_expr, ExprKind::MethodCall, lhs: {:?}, method_name: {:?}, args: {:?}", lhs, method_name, args);
/*

resolve_expr, ExprKind::MethodCall, lhs: Expr { node_id: 13, kind: Variable { module: Local, name: Ident { value: "array", span: Span { filename_id: 1, start: 168, len: 5 } } }, span: Span { filename_id: 1, start: 168, len: 5 } }, method_name: Ident { value: "len", span: Span { filename_id: 1, start: 174, len: 3 } }, args: []
[src/type_checker/mod.rs:235:9] "TypeChecker.analyze" = "TypeChecker.analyze"


*/

self.resolve_expr(lhs)?;
for arg in args {
self.resolve_expr(arg)?;
Expand All @@ -52,6 +61,11 @@ impl NameResCtx {
ExprKind::FieldAccess { lhs, rhs: _ } => {
self.resolve_expr(lhs)?;
}

// ExprKind::ArrayLen { array } => {
// self.resolve_expr(array)?;
// }

ExprKind::BinaryOp {
op: _,
lhs,
Expand Down Expand Up @@ -80,6 +94,9 @@ impl NameResCtx {
self.resolve_expr(expr)?;
}
}
ExprKind::ArrayLen { array} => {
self.resolve_expr(array)?;
}
ExprKind::RepeatedArrayInit { item, size } => {
self.resolve_expr(item)?;
self.resolve_expr(size)?;
Expand Down
1 change: 1 addition & 0 deletions src/name_resolution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl<B: Backend> NAST<B> {
}

pub fn resolve_modules(this_module: Option<UserRepo>, mut ast: AST<B>) -> Result<NAST<B>> {
dbg!("resolve_modules");
let mut ctx = NameResCtx::new(this_module);

// create a map of the imported modules (and how they are aliases)
Expand Down
Loading