import global consts, clean up, test type inference on global consts

This commit is contained in:
gluax 2021-04-26 17:51:19 -04:00
parent 438c20c14d
commit e71c8d99e0
8 changed files with 953 additions and 1004 deletions

View File

@ -1,106 +0,0 @@
// Copyright (C) 2019-2021 Aleo Systems Inc.
// This file is part of the Leo library.
// The Leo library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The Leo library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{
AsgConvertError,
Expression,
ExpressionNode,
FromAst,
InnerVariable,
Node,
Scope,
Span,
Statement,
Variable,
};
use std::cell::{Cell, RefCell};
#[derive(Clone)]
pub struct GlobalConst<'a> {
pub parent: Cell<Option<&'a Statement<'a>>>,
pub span: Option<Span>,
pub variable: &'a Variable<'a>,
pub value: Cell<&'a Expression<'a>>,
}
// impl<'a> Node for GlobalConst<'a> {
// fn span(&self) -> Option<&Span> {
// self.span.as_ref()
// }
// }
// impl<'a> GlobalConst<'a> {
// pub(super) fn init(
// scope: &'a Scope<'a>,
// global_const: &leo_ast::GlobalConst,
// ) -> Result<&'a GlobalConst<'a>, AsgConvertError> {
// let type_ = global_const
// .type_
// .as_ref()
// .map(|x| scope.resolve_ast_type(&x))
// .transpose()?;
// let value = <&Expression<'a>>::from_ast(scope, &global_const.value, type_.clone().map(Into::into))?;
// let type_ = type_.or_else(|| value.get_type());
// let variable = scope.alloc_variable(RefCell::new(InnerVariable {
// id: scope.context.get_id(),
// name: global_const.variable_name.identifier.clone(),
// type_: type_.ok_or_else(|| {
// AsgConvertError::unresolved_type(&global_const.variable_name.identifier.name, &global_const.span)
// })?,
// mutable: global_const.variable_name.mutable,
// const_: false,
// declaration: crate::VariableDeclaration::Definition,
// references: vec![],
// assignments: vec![],
// }));
// let global_const = scope.alloc_global_const(GlobalConst {
// parent: Cell::new(None),
// span: Some(global_const.span.clone()),
// variable,
// value: Cell::new(value),
// });
// Ok(global_const)
// }
// }
// impl<'a> Into<leo_ast::GlobalConst> for &GlobalConst<'a> {
// fn into(self) -> leo_ast::GlobalConst {
// let mut type_ = None::<leo_ast::Type>;
// let variable = self.variable.borrow();
// let variable_name = leo_ast::VariableName {
// mutable: variable.mutable,
// identifier: variable.name.clone(),
// span: variable.name.span.clone(),
// };
// if type_.is_none() {
// type_ = Some((&variable.type_.clone()).into());
// }
// leo_ast::GlobalConst {
// declaration_type: leo_ast::Declare::Let,
// variable_name,
// type_,
// value: self.value.get().into(),
// span: self.span.clone().unwrap_or_default(),
// }
// }
// }

View File

@ -64,8 +64,6 @@ pub struct Program<'a> {
/// Maps circuit name => circuit code block. /// Maps circuit name => circuit code block.
pub circuits: IndexMap<String, &'a Circuit<'a>>, pub circuits: IndexMap<String, &'a Circuit<'a>>,
// pub global_consts: IndexMap<String, (Identifier, &'a ExpressionStatement<'a>)>,
/// Bindings for names and additional program context.
pub scope: &'a Scope<'a>, pub scope: &'a Scope<'a>,
} }
@ -182,8 +180,7 @@ impl<'a> Program<'a> {
let mut imported_functions: IndexMap<String, &'a Function<'a>> = IndexMap::new(); let mut imported_functions: IndexMap<String, &'a Function<'a>> = IndexMap::new();
let mut imported_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new(); let mut imported_circuits: IndexMap<String, &'a Circuit<'a>> = IndexMap::new();
//TODO: Do we want to import global consts? let mut imported_global_consts: IndexMap<String, &'a DefinitionStatement<'a>> = IndexMap::new();
// let imported_global_consts: IndexMap<String, &'a GlobalConst<'a>> = IndexMap::new();
// Prepare locally relevant scope of imports. // Prepare locally relevant scope of imports.
for (package, symbol, span) in imported_symbols.into_iter() { for (package, symbol, span) in imported_symbols.into_iter() {
@ -196,12 +193,15 @@ impl<'a> Program<'a> {
ImportSymbol::All => { ImportSymbol::All => {
imported_functions.extend(resolved_package.functions.clone().into_iter()); imported_functions.extend(resolved_package.functions.clone().into_iter());
imported_circuits.extend(resolved_package.circuits.clone().into_iter()); imported_circuits.extend(resolved_package.circuits.clone().into_iter());
imported_global_consts.extend(resolved_package.global_consts.clone().into_iter());
} }
ImportSymbol::Direct(name) => { ImportSymbol::Direct(name) => {
if let Some(function) = resolved_package.functions.get(&name) { if let Some(function) = resolved_package.functions.get(&name) {
imported_functions.insert(name.clone(), *function); imported_functions.insert(name.clone(), *function);
} else if let Some(circuit) = resolved_package.circuits.get(&name) { } else if let Some(circuit) = resolved_package.circuits.get(&name) {
imported_circuits.insert(name.clone(), *circuit); imported_circuits.insert(name.clone(), *circuit);
} else if let Some(global_const) = resolved_package.global_consts.get(&name) {
imported_global_consts.insert(name.clone(), *global_const);
} else { } else {
return Err(AsgConvertError::unresolved_import( return Err(AsgConvertError::unresolved_import(
&*format!("{}.{}", pretty_package, name), &*format!("{}.{}", pretty_package, name),
@ -214,6 +214,8 @@ impl<'a> Program<'a> {
imported_functions.insert(alias.clone(), *function); imported_functions.insert(alias.clone(), *function);
} else if let Some(circuit) = resolved_package.circuits.get(&name) { } else if let Some(circuit) = resolved_package.circuits.get(&name) {
imported_circuits.insert(alias.clone(), *circuit); imported_circuits.insert(alias.clone(), *circuit);
} else if let Some(global_const) = resolved_package.global_consts.get(&name) {
imported_global_consts.insert(alias.clone(), *global_const);
} else { } else {
return Err(AsgConvertError::unresolved_import( return Err(AsgConvertError::unresolved_import(
&*format!("{}.{}", pretty_package, name), &*format!("{}.{}", pretty_package, name),
@ -231,7 +233,7 @@ impl<'a> Program<'a> {
circuit_self: Cell::new(None), circuit_self: Cell::new(None),
variables: RefCell::new(IndexMap::new()), variables: RefCell::new(IndexMap::new()),
functions: RefCell::new(imported_functions), functions: RefCell::new(imported_functions),
global_consts: RefCell::new(IndexMap::new()), global_consts: RefCell::new(imported_global_consts),
circuits: RefCell::new(imported_circuits), circuits: RefCell::new(imported_circuits),
function: Cell::new(None), function: Cell::new(None),
input: Cell::new(None), input: Cell::new(None),

View File

@ -1,5 +1,7 @@
import test-import.foo as bar; import test-import.foo as bar;
import bar.baz.ONE as UNO;
function main() { function main() {
console.assert(bar() == 1u32); console.assert(bar() == 1u32);
} console.assert(UNO == 1u8);
}

View File

@ -4,4 +4,6 @@ circuit Baz {
circuit Bazzar { circuit Bazzar {
a: u32 a: u32
} }
const ONE: u8 = 1;

View File

@ -5,7 +5,7 @@ import test-import.( // local import
import bar.( // imports directory import import bar.( // imports directory import
Bar, Bar,
baz.(Baz, Bazzar), baz.(Baz, Bazzar, ONE),
bat.bat.Bat, bat.bat.Bat,
); );
@ -23,4 +23,5 @@ function main() {
const car = Car { c: 1u32 }; const car = Car { c: 1u32 };
console.assert(car.c == 1u32); console.assert(car.c == 1u32);
console.assert(ONE == 1u8);
} }

View File

@ -16,4 +16,5 @@ function main() {
const car = Car { c: 1u32 }; const car = Car { c: 1u32 };
console.assert(car.c == 1u32); console.assert(car.c == 1u32);
console.assert(ONE == 1u8);
} }

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@ function two() -> u8 {
return 2u8; return 2u8;
} }
const ONE = 1u8;
function main() { function main() {
const a = 1u8; const a = 1u8;
const b = 1field; const b = 1field;