Skip to content

Commit

Permalink
compiling compiler wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Protryon committed Jan 21, 2021
1 parent 7c03cc6 commit 6cc9589
Show file tree
Hide file tree
Showing 74 changed files with 420 additions and 843 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions asg/src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use crate::Span;
use leo_ast::Error as FormattedError;
use leo_grammar::ParserError;

#[derive(Debug, Error)]
pub enum AsgConvertError {
#[error("{}", _0)]
Error(#[from] FormattedError),
#[error("{}", _0)]
ImportError(FormattedError),
#[error("{}", _0)]
ParserError(#[from] ParserError),
#[error("{}", _0)]
InternalError(String),
}

Expand Down
1 change: 0 additions & 1 deletion asg/src/expression/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ impl FromAst<leo_ast::BinaryExpression> for BinaryExpression {
Some(Type::Integer(_)) | None => (),
Some(x) => return Err(AsgConvertError::unexpected_type(&x.to_string(), Some("integer"), &value.span)),
}

}
}

Expand Down
12 changes: 10 additions & 2 deletions asg/src/expression/circuit_access.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::Span;
use crate::{ Expression, Identifier, Type, Node, ExpressionNode, FromAst, Scope, AsgConvertError, Circuit, CircuitMember, ConstValue, PartialType };
use crate::{ Expression, Identifier, Type, Node, ExpressionNode, FromAst, Scope, AsgConvertError, Circuit, CircuitMember, ConstValue, PartialType, CircuitMemberBody };
use std::sync::{ Weak, Arc };
use std::cell::RefCell;

Expand Down Expand Up @@ -91,7 +91,15 @@ impl FromAst<leo_ast::CircuitMemberAccessExpression> for CircuitAccessExpression
circuit.members.borrow_mut().insert(
value.name.name.clone(),
CircuitMember::Variable(
expected_type.into()
expected_type.clone().into()
)
);
let body = circuit.body.borrow().upgrade().expect("stale input circuit body");

body.members.borrow_mut().insert(
value.name.name.clone(),
CircuitMemberBody::Variable(
expected_type
)
);
} else {
Expand Down
17 changes: 8 additions & 9 deletions asg/src/import.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
use indexmap::IndexMap;
use crate::{ Program, AsgConvertError };
use std::sync::Arc;
use crate::{ Program, AsgConvertError, Span };

pub trait ImportResolver {
fn resolve_package(&self, package_segments: &[&str]) -> Result<Option<Program>, AsgConvertError>;
fn resolve_package(&mut self, package_segments: &[&str], span: &Span) -> Result<Option<Program>, AsgConvertError>;
}

pub struct NullImportResolver;

impl ImportResolver for NullImportResolver {
fn resolve_package(&self, _package_segments: &[&str]) -> Result<Option<Program>, AsgConvertError> {
fn resolve_package(&mut self, _package_segments: &[&str], _span: &Span) -> Result<Option<Program>, AsgConvertError> {
Ok(None)
}
}

pub struct CoreImportResolver<'a, T: ImportResolver + 'static>(pub &'a T);
pub struct CoreImportResolver<'a, T: ImportResolver + 'static>(pub &'a mut T);

impl<'a, T: ImportResolver + 'static> ImportResolver for CoreImportResolver<'a, T> {
fn resolve_package(&self, package_segments: &[&str]) -> Result<Option<Program>, AsgConvertError> {
fn resolve_package(&mut self, package_segments: &[&str], span: &Span) -> Result<Option<Program>, AsgConvertError> {
if package_segments.len() > 0 && package_segments.get(0).unwrap() == &"core" {
Ok(crate::resolve_core_module(&*package_segments[1..].join("."))?)
} else {
self.0.resolve_package(package_segments)
self.0.resolve_package(package_segments, span)
}
}
}
Expand All @@ -30,7 +29,7 @@ pub struct StandardImportResolver;

//todo: move compiler ImportParser here
impl ImportResolver for StandardImportResolver {
fn resolve_package(&self, _package_segments: &[&str]) -> Result<Option<Program>, AsgConvertError> {
fn resolve_package(&mut self, _package_segments: &[&str], _span: &Span) -> Result<Option<Program>, AsgConvertError> {
Ok(None)
}
}
Expand All @@ -40,7 +39,7 @@ pub struct MockedImportResolver {
}

impl ImportResolver for MockedImportResolver {
fn resolve_package(&self, package_segments: &[&str]) -> Result<Option<Program>, AsgConvertError> {
fn resolve_package(&mut self, package_segments: &[&str], _span: &Span) -> Result<Option<Program>, AsgConvertError> {
Ok(self.packages.get(&package_segments.join(".")).cloned())
}
}
85 changes: 52 additions & 33 deletions asg/src/input.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use std::sync::{ Arc, Weak };
use crate::{ Circuit, Variable, Identifier, Type, CircuitMember, WeakType };
use crate::{ Circuit, CircuitBody, Variable, Identifier, Type, CircuitMember, CircuitMemberBody, WeakType, Scope };
use std::cell::RefCell;
use indexmap::IndexMap;

#[derive(Clone)]
pub struct Input {
pub registers: Arc<Circuit>,
pub state: Arc<Circuit>,
pub state_leaf: Arc<Circuit>,
pub record: Arc<Circuit>,
pub container_circuit: Arc<Circuit>,
pub registers: Arc<CircuitBody>,
pub state: Arc<CircuitBody>,
pub state_leaf: Arc<CircuitBody>,
pub record: Arc<CircuitBody>,
pub container_circuit: Arc<CircuitBody>,
pub container: Variable,
}

Expand All @@ -20,32 +20,32 @@ pub const STATE_PSUEDO_CIRCUIT: &str = "$InputState";
pub const STATE_LEAF_PSUEDO_CIRCUIT: &str = "$InputStateLeaf";

impl Input {
pub fn new() -> Self {
let registers = Arc::new(Circuit {
fn make_header(name: &str) -> Arc<Circuit> {
Arc::new(Circuit {
id: uuid::Uuid::new_v4(),
name: RefCell::new(Identifier::new(REGISTERS_PSUEDO_CIRCUIT.to_string())),
name: RefCell::new(Identifier::new(name.to_string())),
body: RefCell::new(Weak::new()),
members: RefCell::new(IndexMap::new()),
});
let record = Arc::new(Circuit {
id: uuid::Uuid::new_v4(),
name: RefCell::new(Identifier::new(RECORD_PSUEDO_CIRCUIT.to_string())),
body: RefCell::new(Weak::new()),
members: RefCell::new(IndexMap::new()),
});
let state = Arc::new(Circuit {
id: uuid::Uuid::new_v4(),
name: RefCell::new(Identifier::new(STATE_PSUEDO_CIRCUIT.to_string())),
body: RefCell::new(Weak::new()),
members: RefCell::new(IndexMap::new()),
});
let state_leaf = Arc::new(Circuit {
id: uuid::Uuid::new_v4(),
name: RefCell::new(Identifier::new(STATE_LEAF_PSUEDO_CIRCUIT.to_string())),
body: RefCell::new(Weak::new()),
members: RefCell::new(IndexMap::new()),
});
})
}

fn make_body(scope: &Scope, circuit: &Arc<Circuit>) -> Arc<CircuitBody> {
let body = Arc::new(CircuitBody {
scope: scope.clone(),
span: None,
circuit: circuit.clone(),
members: RefCell::new(IndexMap::new()),
});
circuit.body.replace(Arc::downgrade(&body));
body
}

pub fn new(scope: &Scope) -> Self {
let registers = Self::make_header(REGISTERS_PSUEDO_CIRCUIT);
let record = Self::make_header(RECORD_PSUEDO_CIRCUIT);
let state = Self::make_header(STATE_PSUEDO_CIRCUIT);
let state_leaf = Self::make_header(STATE_LEAF_PSUEDO_CIRCUIT);

let mut container_members = IndexMap::new();
container_members.insert("registers".to_string(), CircuitMember::Variable(WeakType::Circuit(Arc::downgrade(&registers))));
container_members.insert("record".to_string(), CircuitMember::Variable(WeakType::Circuit(Arc::downgrade(&record))));
Expand All @@ -59,12 +59,31 @@ impl Input {
members: RefCell::new(container_members),
});

let registers_body = Self::make_body(scope, &registers);
let record_body = Self::make_body(scope, &record);
let state_body = Self::make_body(scope, &state);
let state_leaf_body = Self::make_body(scope, &state_leaf);

let mut container_body_members = IndexMap::new();
container_body_members.insert("registers".to_string(), CircuitMemberBody::Variable(Type::Circuit(registers.clone())));
container_body_members.insert("record".to_string(), CircuitMemberBody::Variable(Type::Circuit(record.clone())));
container_body_members.insert("state".to_string(), CircuitMemberBody::Variable(Type::Circuit(state.clone())));
container_body_members.insert("state_leaf".to_string(), CircuitMemberBody::Variable(Type::Circuit(state_leaf.clone())));

let container_circuit_body = Arc::new(CircuitBody {
scope: scope.clone(),
span: None,
circuit: container_circuit.clone(),
members: RefCell::new(container_body_members),
});
container_circuit.body.replace(Arc::downgrade(&container_circuit_body));

Input {
registers,
record,
state,
state_leaf,
container_circuit: container_circuit.clone(),
registers: registers_body,
record: record_body,
state: state_body,
state_leaf: state_leaf_body,
container_circuit: container_circuit_body,
container: Arc::new(RefCell::new(crate::InnerVariable {
id: uuid::Uuid::new_v4(),
name: Identifier::new("input".to_string()),
Expand Down
4 changes: 2 additions & 2 deletions asg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ pub fn load_ast<T: AsRef<Path>, Y: AsRef<str>>(path: T, content: Y) -> Result<le
Ok(leo_ast::Ast::new("load_ast", &ast).into_repr())
}

pub fn load_asg_from_ast<T: ImportResolver + 'static>(content: leo_ast::Program, resolver: &T) -> Result<Program, AsgConvertError> {
pub fn load_asg_from_ast<T: ImportResolver + 'static>(content: leo_ast::Program, resolver: &mut T) -> Result<Program, AsgConvertError> {
InnerProgram::new(&content, resolver)
}

pub fn load_asg<T: ImportResolver + 'static>(content: &str, resolver: &T) -> Result<Program, AsgConvertError> {
pub fn load_asg<T: ImportResolver + 'static>(content: &str, resolver: &mut T) -> Result<Program, AsgConvertError> {
InnerProgram::new(&load_ast("input.leo", content)?, resolver)
}
2 changes: 1 addition & 1 deletion asg/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn resolve_core_module(module: &str) -> Result<Option<Program>, AsgConvertEr
return [0; 32]
}
}
"#, &crate::NullImportResolver)?))
"#, &mut crate::NullImportResolver)?))
},
_ => Ok(None),
}
Expand Down
16 changes: 8 additions & 8 deletions asg/src/program/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl InnerProgram {
3. finalize declared functions
4. resolve all asg nodes
*/
pub fn new<'a, T: ImportResolver + 'static>(value: &leo_ast::Program, import_resolver: &'a T) -> Result<Program, AsgConvertError> {
pub fn new<'a, T: ImportResolver + 'static>(value: &leo_ast::Program, import_resolver: &'a mut T) -> Result<Program, AsgConvertError> {
// TODO: right now if some program A is imported from programs B and C, it will be copied to both, which is not optimal -- needs fixed

// recursively extract our imported symbols
Expand All @@ -83,18 +83,18 @@ impl InnerProgram {
}

// package list
let mut deduplicated_imports: IndexSet<Vec<String>> = IndexSet::new();
for (package, _symbol, _span) in imported_symbols.iter() {
deduplicated_imports.insert(package.clone());
let mut deduplicated_imports: IndexMap<Vec<String>, Span> = IndexMap::new();
for (package, _symbol, span) in imported_symbols.iter() {
deduplicated_imports.insert(package.clone(), span.clone());
}

let wrapped_resolver = crate::CoreImportResolver(import_resolver);
let mut wrapped_resolver = crate::CoreImportResolver(import_resolver);
// load imported programs
let mut resolved_packages: IndexMap<Vec<String>, Program> = IndexMap::new();
for package in deduplicated_imports.iter() {
for (package, span) in deduplicated_imports.iter() {
let pretty_package = package.join(".");

let resolved_package = match wrapped_resolver.resolve_package(&package.iter().map(|x| &**x).collect::<Vec<_>>()[..])? {
let resolved_package = match wrapped_resolver.resolve_package(&package.iter().map(|x| &**x).collect::<Vec<_>>()[..], span)? {
Some(x) => x,
None => return Err(AsgConvertError::unresolved_import(&*pretty_package, &Span::default())), // todo: better span
};
Expand Down Expand Up @@ -158,14 +158,14 @@ impl InnerProgram {
}

let scope = Arc::new(RefCell::new(InnerScope {
input: Some(Input::new(&import_scope)), // we use import_scope to avoid recursive scope ref here
id: uuid::Uuid::new_v4(),
parent_scope: Some(import_scope),
circuit_self: None,
variables: IndexMap::new(),
functions: IndexMap::new(),
circuits: proto_circuits.iter().map(|(name, circuit)| (name.clone(), circuit.clone())).collect(),
function: None,
input: Some(Input::new()),
}));

for (name, circuit) in value.circuits.iter() {
Expand Down
2 changes: 1 addition & 1 deletion asg/src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl InnerScope {
}))
}

pub(crate) fn resolve_ast_type(&self, type_: &leo_ast::Type) -> Result<Type, AsgConvertError> {
pub fn resolve_ast_type(&self, type_: &leo_ast::Type) -> Result<Type, AsgConvertError> {
use leo_ast::Type::*;
Ok(match type_ {
Address => Type::Address,
Expand Down
4 changes: 2 additions & 2 deletions asg/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ mod pass;
mod fail;

fn load_asg(content: &str) -> Result<Program, AsgConvertError> {
leo_asg::load_asg(content, &NullImportResolver)
leo_asg::load_asg(content, &mut NullImportResolver)
}

fn load_asg_imports<T: ImportResolver + 'static>(content: &str, imports: &T) -> Result<Program, AsgConvertError> {
fn load_asg_imports<T: ImportResolver + 'static>(content: &str, imports: &mut T) -> Result<Program, AsgConvertError> {
leo_asg::load_asg(content, imports)
}

Expand Down
2 changes: 1 addition & 1 deletion asg/tests/pass/form_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn test_imports() {
"#;
println!("{}", serde_json::to_string(&crate::load_ast("test-import.leo", test_import).unwrap()).unwrap());
println!("{}", serde_json::to_string(&crate::load_ast("test.leo", program_string).unwrap()).unwrap());
let asg = crate::load_asg_imports(program_string, &imports).unwrap();
let asg = crate::load_asg_imports(program_string, &mut imports).unwrap();
let reformed_ast = leo_asg::reform_ast(&asg);
println!("{}", serde_json::to_string(&reformed_ast).unwrap());
panic!();
Expand Down
14 changes: 7 additions & 7 deletions asg/tests/pass/import/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ fn test_basic() {
let mut imports = mocked_resolver();
imports.packages.insert("test-import".to_string(), load_asg(include_str!("src/test-import.leo")).unwrap());
let program_string = include_str!("basic.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}

#[test]
fn test_multiple() {
let mut imports = mocked_resolver();
imports.packages.insert("test-import".to_string(), load_asg(include_str!("src/test-import.leo")).unwrap());
let program_string = include_str!("multiple.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}

#[test]
Expand All @@ -38,7 +38,7 @@ fn test_star() {
imports.packages.insert("test-import".to_string(), load_asg(include_str!("src/test-import.leo")).unwrap());

let program_string = include_str!("star.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}

#[test]
Expand All @@ -47,7 +47,7 @@ fn test_alias() {
imports.packages.insert("test-import".to_string(), load_asg(include_str!("src/test-import.leo")).unwrap());

let program_string = include_str!("alias.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}

// naming tests
Expand All @@ -59,7 +59,7 @@ fn test_name() {
imports.packages.insert("a-9".to_string(), load_asg(include_str!("src/a-9.leo")).unwrap());

let program_string = include_str!("names.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}

// more complex tests
Expand All @@ -74,7 +74,7 @@ fn test_many_import() {
imports.packages.insert("car".to_string(), load_asg(include_str!("imports/car/src/lib.leo")).unwrap());

let program_string = include_str!("many_import.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}

#[test]
Expand All @@ -88,5 +88,5 @@ fn test_many_import_star() {
imports.packages.insert("car".to_string(), load_asg(include_str!("imports/car/src/lib.leo")).unwrap());

let program_string = include_str!("many_import_star.leo");
load_asg_imports(program_string, &imports).unwrap();
load_asg_imports(program_string, &mut imports).unwrap();
}
Loading

0 comments on commit 6cc9589

Please sign in to comment.