move types into new static-check module

This commit is contained in:
collin 2020-10-12 12:32:29 -07:00
parent e0750158f5
commit d29d01f4ff
53 changed files with 95 additions and 1486 deletions

17
Cargo.lock generated
View File

@ -1282,7 +1282,7 @@ version = "1.0.3"
dependencies = [
"leo-ast",
"leo-imports",
"leo-symbol-table",
"leo-static-check",
"leo-typed",
"serde",
"thiserror",
@ -1347,7 +1347,7 @@ dependencies = [
"leo-input",
"leo-package",
"leo-state",
"leo-symbol-table",
"leo-static-check",
"notify",
"num-bigint",
"rand",
@ -1408,7 +1408,7 @@ dependencies = [
]
[[package]]
name = "leo-symbol-table"
name = "leo-static-check"
version = "1.0.3"
dependencies = [
"leo-ast",
@ -1432,17 +1432,6 @@ dependencies = [
"snarkos-models",
]
[[package]]
name = "leo-types"
version = "1.0.3"
dependencies = [
"leo-ast",
"leo-imports",
"leo-typed",
"serde",
"thiserror",
]
[[package]]
name = "libc"
version = "0.2.76"

View File

@ -36,9 +36,8 @@ members = [
"linter",
"package",
"typed",
"types",
"state",
"symbol-table",
"static-check",
]
[dependencies.leo-compiler]
@ -73,8 +72,8 @@ version = "1.0.3"
path = "./state"
version = "1.0.3"
[dependencies.leo-symbol-table]
path = "./symbol-table"
[dependencies.leo-static-check]
path = "./static-check"
version = "1.0.3"
[dependencies.snarkos-algorithms]

View File

@ -25,8 +25,8 @@ version = "1.0.3"
path = "../imports"
version = "1.0.3"
[dependencies.leo-symbol-table]
path = "../symbol-table"
[dependencies.leo-static-check]
path = "../static-check"
version = "1.0.3"
[dependencies.leo-typed]

View File

@ -16,7 +16,7 @@
use leo_typed::{Expression, Function, Identifier, Program, Span, Statement};
use leo_symbol_table::{ExtendedType, FunctionType, SymbolTable};
use leo_static_check::{FunctionType, SymbolTable, Type};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
@ -235,7 +235,7 @@ impl TypeAssertion {
/// A `Type` or a `TypeVariable` in a `TypeAssertion`.
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum TypeElement {
Type(ExtendedType),
Type(Type),
Variable(TypeVariable),
}
@ -256,7 +256,7 @@ impl TypeElement {
/// Return a boolean `TypeElement`.
///
pub fn boolean() -> Self {
TypeElement::Type(ExtendedType::Boolean)
TypeElement::Type(Type::Boolean)
}
///

View File

@ -17,7 +17,7 @@
use leo_ast::LeoAst;
use leo_dynamic_check::DynamicCheck;
use leo_symbol_table::SymbolTable;
use leo_symbol_table::OldSymbolTable;
use leo_typed::LeoTypedAst;
use std::path::PathBuf;
@ -45,7 +45,7 @@ impl TestDynamicCheck {
let program = typed.into_repr();
// Create symbol table.
let mut symbol_table = SymbolTable::new(None);
let mut symbol_table = OldSymbolTable::new(None);
// Load symbols into symbol table.
symbol_table.pass_one(&program).unwrap();

View File

@ -1,5 +1,5 @@
[package]
name = "leo-symbol-table"
name = "leo-static-check"
version = "1.0.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Stores user-defined variables during type resolution"

View File

@ -23,5 +23,8 @@ pub use self::attributes::*;
pub mod errors;
pub use self::errors::*;
pub mod symbol_table;
pub use self::symbol_table::*;
pub mod types;
pub use self::types::*;

View File

@ -14,14 +14,13 @@
// 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::{CircuitType, FunctionType, ResolvedNode, SymbolTableError, VariableType};
use crate::{CircuitType, FunctionType, ParameterType, SymbolTableError};
use leo_typed::{Circuit, Function, Identifier, Program as UnresolvedProgram};
use leo_imports::ImportParser;
use std::collections::HashMap;
/// A abstract data type that tracks the current bindings of identifier
/// names to types in a Leo program.
/// A abstract data type that builds symbol tables for functions and circuits
///
/// A symbol table has access to all function and circuit names in its
/// parent's symbol table.
@ -29,13 +28,13 @@ use std::collections::HashMap;
/// Children cannot access names in another sibling's symbol table.
#[derive(Clone)]
pub struct SymbolTable {
/// Maps variable name -> variable type.
variables: HashMap<String, VariableType>,
/// Maps name -> parameter type.
names: HashMap<String, ParameterType>,
/// Maps circuit name -> circuit type.
circuits: HashMap<String, CircuitType>,
///Maps function name -> function type.
/// Maps function name -> function type.
functions: HashMap<String, FunctionType>,
/// The parent of this symbol table.
@ -48,7 +47,7 @@ impl SymbolTable {
///
pub fn new(parent: Option<Box<SymbolTable>>) -> Self {
SymbolTable {
variables: HashMap::new(),
names: HashMap::new(),
circuits: HashMap::new(),
functions: HashMap::new(),
parent,
@ -56,14 +55,14 @@ impl SymbolTable {
}
///
/// Insert a variable into the symbol table from a given name and variable type.
/// Insert a function or circuit name into the symbol table from a given name and variable type.
///
/// If the symbol table did not have this name present, `None` is returned.
/// If the symbol table did have this name present, the variable type is updated, and the old
/// variable type is returned.
///
pub fn insert_variable(&mut self, name: String, variable_type: VariableType) -> Option<VariableType> {
self.variables.insert(name, variable_type)
pub fn insert_name(&mut self, name: String, variable_type: ParameterType) -> Option<ParameterType> {
self.names.insert(name, variable_type)
}
///
@ -90,18 +89,18 @@ impl SymbolTable {
self.functions.insert(identifier.name, function_type)
}
///
/// Returns a reference to the variable type corresponding to the name.
///
/// If the symbol table did not have this name present, then `None` is returned.
///
pub fn get_variable(&self, name: &String) -> Option<&VariableType> {
// Lookup variable name in symbol table.
match self.variables.get(name) {
Some(variable) => Some(variable),
None => None,
}
}
// ///
// /// Returns a reference to the variable type corresponding to the name.
// ///
// /// If the symbol table did not have this name present, then `None` is returned.
// ///
// pub fn get_variable(&self, name: &String) -> Option<&ParameterType> {
// // Lookup variable name in symbol table.
// match self.names.get(name) {
// Some(variable) => Some(variable),
// None => None,
// }
// }
///
/// Returns a reference to the circuit type corresponding to the name.
@ -163,7 +162,7 @@ impl SymbolTable {
// Iterate over circuit names and definitions.
for (identifier, circuit) in circuits.iter() {
// Attempt to insert the circuit name into the symbol table.
let duplicate = self.insert_variable(identifier.to_string(), VariableType::from(circuit.clone()));
let duplicate = self.insert_name(identifier.to_string(), ParameterType::from(circuit.clone()));
// Check that the circuit name is unique.
if duplicate.is_some() {
@ -190,7 +189,7 @@ impl SymbolTable {
// Iterate over function names and definitions.
for (identifier, function) in functions.iter() {
// Attempt to insert the function name into the symbol table.
let duplicate = self.insert_variable(identifier.to_string(), VariableType::from(function.clone()));
let duplicate = self.insert_name(identifier.to_string(), ParameterType::from(function.clone()));
// Check that the function name is unique.
if duplicate.is_some() {
@ -221,7 +220,7 @@ impl SymbolTable {
let identifier = circuit.circuit_name.clone();
// Resolve unknown types in the unresolved circuit definition.
let circuit_type = CircuitType::resolve(self, circuit.clone())?;
let circuit_type = CircuitType::new(self, circuit.clone())?;
// Attempt to insert the circuit definition into the symbol table.
self.insert_circuit(identifier, circuit_type);
@ -247,7 +246,7 @@ impl SymbolTable {
let identifier = function.identifier.clone();
// Resolve unknown types in the unresolved function definition.
let function_type = FunctionType::resolve(self, function.clone())?;
let function_type = FunctionType::new(&self, function.clone())?;
// Attempt to insert the function definition into the symbol table.
self.insert_function(identifier, function_type);

View File

@ -18,7 +18,6 @@ use crate::{
types::circuits::{CircuitFunctionType, CircuitVariableType},
Attribute,
FunctionType,
ResolvedNode,
SymbolTable,
Type,
TypeError,
@ -43,17 +42,14 @@ pub struct CircuitType {
pub functions: Vec<CircuitFunctionType>,
}
impl ResolvedNode for CircuitType {
type Error = TypeError;
type UnresolvedNode = Circuit;
impl CircuitType {
///
/// Return a new `CircuitType` from a given `Circuit` definition.
///
/// Performs a lookup in the given symbol table if the circuit definition contains
/// user-defined types.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
pub fn new(table: &SymbolTable, unresolved: Circuit) -> Result<Self, TypeError> {
let circuit_identifier = unresolved.circuit_name;
let mut variables = vec![];
let mut functions = vec![];
@ -109,9 +105,7 @@ impl ResolvedNode for CircuitType {
functions,
})
}
}
impl CircuitType {
///
/// Returns the type of a circuit member.
///

View File

@ -16,7 +16,6 @@
use crate::{
types::functions::{FunctionInputType, FunctionOutputType},
ResolvedNode,
SymbolTable,
TypeError,
};
@ -47,7 +46,7 @@ impl FunctionType {
/// Performs a lookup in the given symbol table if the function definition contains
/// user-defined types.
///
pub fn new(table: &mut SymbolTable, unresolved: Function) -> Result<Self, TypeError> {
pub fn new(table: &SymbolTable, unresolved: Function) -> Result<Self, TypeError> {
let mut inputs_resolved = vec![];
// Type check function inputs
@ -66,22 +65,6 @@ impl FunctionType {
})
}
///
/// Resolve a function definition and insert it into the given symbol table.
///
pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> {
// Get the identifier of the function.
let function_identifier = unresolved_function.identifier.clone();
// Resolve the function definition into a function type.
let function = Self::new(table, unresolved_function)?;
// Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table.
table.insert_function(function_identifier, function);
Ok(())
}
///
/// Return a new `FunctionType` from a given `Function` definition.
///
@ -92,7 +75,7 @@ impl FunctionType {
/// is used as the type.
///
pub fn from_circuit(
table: &mut SymbolTable,
table: &SymbolTable,
circuit_name: Identifier,
unresolved_function: Function,
) -> Result<Self, TypeError> {
@ -119,4 +102,20 @@ impl FunctionType {
output,
})
}
///
/// Resolve a function definition and insert it into the given symbol table.
///
pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> {
// Get the identifier of the function.
let function_identifier = unresolved_function.identifier.clone();
// Resolve the function definition into a function type.
let function = Self::new(table, unresolved_function)?;
// Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table.
table.insert_function(function_identifier, function);
Ok(())
}
}

View File

@ -14,7 +14,7 @@
// 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::{FunctionInputVariableType, ParameterType, ResolvedNode, SymbolTable, Type, TypeError};
use crate::{FunctionInputVariableType, ParameterType, SymbolTable, Type, TypeError};
use leo_typed::{FunctionInput, Identifier};
use serde::{Deserialize, Serialize};
@ -26,23 +26,6 @@ pub enum FunctionInputType {
}
impl FunctionInputType {
///
/// Return a new `FunctionInputType` from a given `FunctionInput`.
///
/// Performs a lookup in the given symbol table if the function input contains
/// user-defined types.
///
pub fn new(table: &mut SymbolTable, unresolved: FunctionInput) -> Result<Self, TypeError> {
Ok(match unresolved {
FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier),
FunctionInput::Variable(variable) => {
let variable_resolved = FunctionInputVariableType::new(table, variable)?;
FunctionInputType::Variable(variable_resolved)
}
})
}
///
/// Return the `Identifier` containing name and span information about the current function input.
///
@ -63,6 +46,23 @@ impl FunctionInputType {
}
}
///
/// Return a new `FunctionInputType` from a given `FunctionInput`.
///
/// Performs a lookup in the given symbol table if the function input contains
/// user-defined types.
///
pub fn new(table: &SymbolTable, unresolved: FunctionInput) -> Result<Self, TypeError> {
Ok(match unresolved {
FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier),
FunctionInput::Variable(variable) => {
let variable_resolved = FunctionInputVariableType::new(table, variable)?;
FunctionInputType::Variable(variable_resolved)
}
})
}
///
/// Return a new `FunctionInputType` from a given `FunctionInput`.
///
@ -73,7 +73,7 @@ impl FunctionInputType {
/// is used as the type.
///
pub fn new_from_circuit(
table: &mut SymbolTable,
table: &SymbolTable,
unresolved: FunctionInput,
circuit_name: Identifier,
) -> Result<Self, TypeError> {

View File

@ -14,7 +14,7 @@
// 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::{Attribute, ParameterType, ResolvedNode, SymbolTable, Type, TypeError};
use crate::{Attribute, ParameterType, SymbolTable, Type, TypeError};
use leo_typed::{FunctionInputVariable, Identifier, Span};
use serde::{Deserialize, Serialize};
@ -40,7 +40,7 @@ impl FunctionInputVariableType {
///
/// Performs a lookup in the given symbol table if the type is user-defined.
///
pub fn new(table: &mut SymbolTable, unresolved: FunctionInputVariable) -> Result<Self, TypeError> {
pub fn new(table: &SymbolTable, unresolved: FunctionInputVariable) -> Result<Self, TypeError> {
let type_ = Type::new(table, unresolved.type_, unresolved.span.clone())?;
let attributes = if unresolved.mutable {
vec![Attribute::Mutable]
@ -65,7 +65,7 @@ impl FunctionInputVariableType {
/// identifier is used as the type.
///
pub fn new_from_circuit(
table: &mut SymbolTable,
table: &SymbolTable,
unresolved_function_input: FunctionInputVariable,
circuit_name: Identifier,
) -> Result<Self, TypeError> {
@ -98,6 +98,6 @@ impl FunctionInputVariableType {
let key = self.identifier.name.clone();
let value = ParameterType::from(self.clone());
table.insert_variable(key, value)
table.insert_name(key, value)
}
}

View File

@ -14,7 +14,7 @@
// 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::{ResolvedNode, SymbolTable, Type, TypeError};
use crate::{SymbolTable, Type, TypeError};
use leo_typed::{Identifier, Span, Type as UnresolvedType};
@ -33,7 +33,7 @@ impl FunctionOutputType {
/// Performs a lookup in the given symbol table if the return type is user-defined.
///
pub(crate) fn new(
table: &mut SymbolTable,
table: &SymbolTable,
function_output: Option<UnresolvedType>,
span: Span,
) -> Result<Self, TypeError> {
@ -54,7 +54,7 @@ impl FunctionOutputType {
/// identifier is used as the type.
///
pub fn new_from_circuit(
table: &mut SymbolTable,
table: &SymbolTable,
circuit_name: Identifier,
unresolved: Option<UnresolvedType>,
span: Span,

View File

@ -13,7 +13,7 @@
// 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::{ResolvedNode, SymbolTable, TypeError, TypeVariable};
use crate::{SymbolTable, TypeError, TypeVariable};
use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType};
use serde::{Deserialize, Serialize};
@ -45,7 +45,7 @@ impl Type {
///
/// Return a new type from the given unresolved type.
///
pub fn new(table: &mut SymbolTable, type_: UnresolvedType, span: Span) -> Result<Self, TypeError> {
pub fn new(table: &SymbolTable, type_: UnresolvedType, span: Span) -> Result<Self, TypeError> {
Ok(match type_ {
UnresolvedType::Address => Type::Address,
UnresolvedType::Boolean => Type::Boolean,
@ -89,7 +89,7 @@ impl Type {
/// If this type is SelfType, return the circuit's type.
///
pub fn new_from_circuit(
table: &mut SymbolTable,
table: &SymbolTable,
type_: UnresolvedType,
circuit_name: Identifier,
span: Span,

View File

@ -17,7 +17,7 @@
pub mod symbol_table;
use leo_ast::LeoAst;
use leo_symbol_table::{SymbolTable, SymbolTableError};
use leo_symbol_table::{OldSymbolTable, SymbolTableError};
use leo_typed::LeoTypedAst;
use std::path::PathBuf;
@ -59,7 +59,7 @@ impl TestSymbolTable {
let program = self.typed.into_repr();
// Create new symbol table.
let symbol_table = &mut SymbolTable::new(None);
let symbol_table = &mut OldSymbolTable::new(None);
// Run the first pass to check for duplicate names.
symbol_table.pass_one(&program).unwrap();
@ -78,7 +78,7 @@ impl TestSymbolTable {
let program = self.typed.into_repr();
// Create new symbol table.
let symbol_table = &mut SymbolTable::new(None);
let symbol_table = &mut OldSymbolTable::new(None);
// Run pass one and expect an error.
let error = symbol_table.pass_one(&program).unwrap_err();
@ -99,7 +99,7 @@ impl TestSymbolTable {
let program = self.typed.into_repr();
// Create a new symbol table.
let symbol_table = &mut SymbolTable::new(None);
let symbol_table = &mut OldSymbolTable::new(None);
// Run the pass one and expect no errors.
symbol_table.pass_one(&program).unwrap();

View File

@ -1,141 +0,0 @@
// Copyright (C) 2019-2020 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::ExtendedType;
use leo_typed::{Error as FormattedError, Identifier, Span};
use std::path::PathBuf;
/// Errors encountered when resolving types.
#[derive(Debug, Error)]
pub enum TypeError {
#[error("{}", _0)]
Error(#[from] FormattedError),
}
impl TypeError {
///
/// Set the filepath for the error stacktrace.
///
pub fn set_path(&mut self, path: PathBuf) {
match self {
TypeError::Error(error) => error.set_path(path),
}
}
///
/// Return a new formatted error with a given message and span information.
///
fn new_from_span(message: String, span: Span) -> Self {
TypeError::Error(FormattedError::new_from_span(message, span))
}
///
/// Expected an array type from the given expression.
///
pub fn invalid_array(actual: &ExtendedType, span: Span) -> Self {
let message = format!("Expected array type, found type `{}`.", actual);
Self::new_from_span(message, span)
}
///
/// Expected a circuit type from the given expression.
///
pub fn invalid_circuit(actual: &ExtendedType, span: Span) -> Self {
let message = format!("Expected circuit type, found type `{}`.", actual);
Self::new_from_span(message, span)
}
///
/// Expected a function type from the given expression.
///
pub fn invalid_function(actual: &ExtendedType, span: Span) -> Self {
let message = format!("Expected function type, found type `{}`.", actual);
Self::new_from_span(message, span)
}
///
/// Expected an integer type from the given expression.
///
pub fn invalid_integer(actual: &ExtendedType, span: Span) -> Self {
let message = format!("Expected integer type, found type `{}`.", actual);
Self::new_from_span(message, span)
}
///
/// Expected a tuple type from the given expression.
///
pub fn invalid_tuple(actual: &ExtendedType, span: Span) -> Self {
let message = format!("Expected tuple type, found type `{}`.", actual);
Self::new_from_span(message, span)
}
///
/// The value of the expression does not match the given explicit type.
///
pub fn mismatched_types(expected: &ExtendedType, actual: &ExtendedType, span: Span) -> Self {
let message = format!("Expected type `{}`, found type `{}`.", expected, actual);
Self::new_from_span(message, span)
}
///
/// The `Self` keyword was used outside of a circuit.
///
pub fn self_not_available(span: Span) -> Self {
let message = format!("Type `Self` is only available in circuit definitions and circuit functions.");
Self::new_from_span(message, span)
}
///
/// Found an unknown circuit name.
///
pub fn undefined_circuit(identifier: Identifier) -> Self {
let message = format!(
"Type circuit `{}` must be defined before it is used in an expression.",
identifier.name
);
Self::new_from_span(message, identifier.span)
}
///
/// Found an unknown circuit member name.
///
pub fn undefined_circuit_member(identifier: Identifier) -> Self {
let message = format!("Circuit has no member `{}`.", identifier.name);
Self::new_from_span(message, identifier.span)
}
///
/// Found an unknown function name.
///
pub fn undefined_function(identifier: Identifier) -> Self {
let message = format!(
"Type function `{}` must be defined before it is used in an expression.",
identifier.name
);
Self::new_from_span(message, identifier.span)
}
}

View File

@ -1,52 +0,0 @@
// Copyright (C) 2019-2020 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/>.
#[macro_use]
extern crate thiserror;
pub mod attributes;
pub use self::attributes::*;
pub mod errors;
pub use self::errors::*;
pub mod symbol_table;
pub use self::symbol_table::*;
pub mod types;
pub use self::types::*;
/// A resolved node in an abstract syntax tree (AST).
///
/// Resolved nodes can be any function, statement, expression, type, etc. in an AST.
/// Resolved nodes should not contain any illegal types.
/// Resolved nodes should not contain any implicit types.
pub trait ResolvedNode {
/// The expected error type if the type resolution fails.
type Error;
/// The unresolved AST node that is being resolved.
type UnresolvedNode;
///
/// Returns a resolved AST representation given an unresolved AST representation.
///
/// User-defined types are looked up using the given symbol table.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error>
where
Self: std::marker::Sized;
}

View File

@ -1,144 +0,0 @@
// Copyright (C) 2019-2020 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::{
types::circuits::{CircuitFunctionType, CircuitVariableType},
Attribute,
ExtendedType,
FunctionType,
ResolvedNode,
SymbolTable,
TypeError,
};
use leo_typed::{Circuit, CircuitMember, Identifier};
use serde::{Deserialize, Serialize};
/// Stores circuit definition details.
///
/// This type should be added to the circuit symbol table for a resolved syntax tree.
/// This is a user-defined type.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CircuitType {
/// The name of the circuit definition.
pub identifier: Identifier,
/// The circuit variables.
pub variables: Vec<CircuitVariableType>,
/// The circuit functions.
pub functions: Vec<CircuitFunctionType>,
}
impl ResolvedNode for CircuitType {
type Error = TypeError;
type UnresolvedNode = Circuit;
///
/// Return a new `CircuitType` from a given `Circuit` definition.
///
/// Performs a lookup in the given symbol table if the circuit definition contains
/// user-defined types.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
let circuit_identifier = unresolved.circuit_name;
let mut variables = vec![];
let mut functions = vec![];
// Resolve the type of every circuit member.
for member in unresolved.members {
match member {
CircuitMember::CircuitVariable(is_mutable, variable_identifier, type_) => {
// Resolve the type of the circuit member variable.
let type_ = ExtendedType::from_circuit(
table,
type_,
circuit_identifier.clone(),
circuit_identifier.span.clone(),
)?;
// Check if the circuit member variable is mutable.
let attributes = if is_mutable { vec![Attribute::Mutable] } else { vec![] };
// Create a new circuit variable type.
let variable = CircuitVariableType {
identifier: variable_identifier,
type_,
attributes,
};
// Store the circuit variable type.
variables.push(variable);
}
CircuitMember::CircuitFunction(is_static, function) => {
// Resolve the type of the circuit member function.
let function_type = FunctionType::from_circuit(table, circuit_identifier.clone(), function)?;
// Check if the circuit member function is static.
let attributes = if is_static { vec![Attribute::Static] } else { vec![] };
// Create a new circuit function type.
let function = CircuitFunctionType {
function: function_type,
attributes,
};
// Store the circuit function type.
functions.push(function);
}
}
}
// Return a new circuit type.
Ok(CircuitType {
identifier: circuit_identifier.clone(),
variables,
functions,
})
}
}
impl CircuitType {
///
/// Returns the type of a circuit member.
///
/// If the member is a circuit variable, then the type of the variable is returned.
/// If the member is a circuit function, then the return type of the function is returned.
///
pub fn member_type(&self, identifier: &Identifier) -> Result<&ExtendedType, TypeError> {
// Check if the circuit member is a circuit variable.
let matched_variable = self
.variables
.iter()
.find(|variable| variable.identifier.eq(identifier));
match matched_variable {
Some(variable) => Ok(&variable.type_),
None => {
// Check if the circuit member is a circuit function.
let matched_function = self
.functions
.iter()
.find(|function| function.function.identifier.eq(identifier));
match matched_function {
Some(function) => Ok(&function.function.output.type_),
None => Err(TypeError::undefined_circuit_member(identifier.clone())),
}
}
}
}
}

View File

@ -1,30 +0,0 @@
// Copyright (C) 2019-2020 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::{Attribute, ExtendedType};
use leo_typed::Identifier;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CircuitVariableType {
/// The name of the circuit variable
pub identifier: Identifier,
/// The type of the circuit variable
pub type_: ExtendedType,
/// The attributes of the circuit variable
pub attributes: Vec<Attribute>,
}

View File

@ -1,127 +0,0 @@
// Copyright (C) 2019-2020 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::{
types::functions::{FunctionInputType, FunctionOutputType},
ResolvedNode,
SymbolTable,
TypeError,
};
use leo_typed::{Function, Identifier};
use serde::{Deserialize, Serialize};
/// Stores function definition details.
///
/// This type should be added to the function symbol table for a resolved syntax tree.
/// This is a user-defined type.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FunctionType {
/// The name of the function definition.
pub identifier: Identifier,
/// The function inputs.
pub inputs: Vec<FunctionInputType>,
/// The function output.
pub output: FunctionOutputType,
}
impl ResolvedNode for FunctionType {
type Error = TypeError;
type UnresolvedNode = Function;
///
/// Return a new `FunctionType` from a given `Function` definition.
///
/// Performs a lookup in the given symbol table if the function definition contains
/// user-defined types.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
let mut inputs_resolved = vec![];
// Type check function inputs
for input in unresolved.input {
let input = FunctionInputType::resolve(table, input)?;
inputs_resolved.push(input);
}
// Type check function output
let output = FunctionOutputType::resolve(table, (unresolved.output, unresolved.span))?;
Ok(FunctionType {
identifier: unresolved.identifier,
inputs: inputs_resolved,
output,
})
}
}
impl FunctionType {
///
/// Resolve a function definition and insert it into the given symbol table.
///
pub fn insert_definition(table: &mut SymbolTable, unresolved_function: Function) -> Result<(), TypeError> {
// Get the identifier of the function.
let function_identifier = unresolved_function.identifier.clone();
// Resolve the function definition into a function type.
let function = Self::resolve(table, unresolved_function)?;
// Insert (function_identifier -> function_type) as a (key -> value) pair in the symbol table.
table.insert_function(function_identifier, function);
Ok(())
}
///
/// Return a new `FunctionType` from a given `Function` definition.
///
/// Performs a lookup in the given symbol table if the function definition contains
/// user-defined types.
///
/// If the function definition contains the `Self` keyword, then the given circuit identifier
/// is used as the type.
///
pub fn from_circuit(
table: &mut SymbolTable,
circuit_name: Identifier,
unresolved_function: Function,
) -> Result<Self, TypeError> {
let function_identifier = unresolved_function.identifier;
let mut inputs = vec![];
// Type check function inputs.
for unresolved_input in unresolved_function.input {
let input = FunctionInputType::from_circuit(table, unresolved_input, circuit_name.clone())?;
inputs.push(input);
}
// Type check function output.
let output = FunctionOutputType::from_circuit(
table,
circuit_name.clone(),
unresolved_function.output,
unresolved_function.span,
)?;
Ok(FunctionType {
identifier: function_identifier.clone(),
inputs,
output,
})
}
}

View File

@ -1,109 +0,0 @@
// Copyright (C) 2019-2020 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::{ExtendedType, FunctionInputVariableType, ResolvedNode, SymbolTable, TypeError, VariableType};
use leo_typed::{FunctionInput, Identifier};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum FunctionInputType {
InputKeyword(Identifier),
Variable(FunctionInputVariableType),
}
impl ResolvedNode for FunctionInputType {
type Error = TypeError;
type UnresolvedNode = FunctionInput;
///
/// Return a new `FunctionInputType` from a given `FunctionInput`.
///
/// Performs a lookup in the given symbol table if the function input contains
/// user-defined types.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
Ok(match unresolved {
FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier),
FunctionInput::Variable(variable) => {
let variable_resolved = FunctionInputVariableType::resolve(table, variable)?;
FunctionInputType::Variable(variable_resolved)
}
})
}
}
impl FunctionInputType {
///
/// Return the `Identifier` containing name and span information about the current function input.
///
pub fn identifier(&self) -> &Identifier {
match self {
FunctionInputType::InputKeyword(identifier) => identifier,
FunctionInputType::Variable(variable) => &variable.identifier,
}
}
///
/// Return the `Type` of the current function input.
///
pub fn type_(&self) -> &ExtendedType {
match self {
FunctionInputType::InputKeyword(_) => unimplemented!("ERROR: input type not implemented"),
FunctionInputType::Variable(variable) => &variable.type_,
}
}
///
/// Return a new `FunctionInputType` from a given `FunctionInput`.
///
/// Performs a lookup in the given symbol table if the function input contains
/// user-defined types.
///
/// If the type of the function input is the `Self` keyword, then the given circuit identifier
/// is used as the type.
///
pub fn from_circuit(
table: &mut SymbolTable,
unresolved: FunctionInput,
circuit_name: Identifier,
) -> Result<Self, TypeError> {
Ok(match unresolved {
FunctionInput::InputKeyword(identifier) => FunctionInputType::InputKeyword(identifier),
FunctionInput::Variable(unresolved_function_input) => {
let function_input =
FunctionInputVariableType::from_circuit(table, unresolved_function_input, circuit_name)?;
FunctionInputType::Variable(function_input)
}
})
}
///
/// Insert the current function input type into the given symbol table.
///
/// If the symbol table did not have this name present, `None` is returned.
///
pub fn insert(&self, table: &mut SymbolTable) -> Option<VariableType> {
match self {
FunctionInputType::Variable(variable) => variable.insert(table),
FunctionInputType::InputKeyword(_identifier) => {
unimplemented!("uncomment when support for input types is added")
}
}
}
}

View File

@ -1,108 +0,0 @@
// Copyright (C) 2019-2020 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::{Attribute, ExtendedType, ResolvedNode, SymbolTable, TypeError, VariableType};
use leo_typed::{FunctionInputVariable, Identifier, Span};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FunctionInputVariableType {
/// Name of function input.
pub identifier: Identifier,
/// Type of function input.
pub type_: ExtendedType,
/// The attributes of the function input.
pub attributes: Vec<Attribute>,
/// The span of the function input.
pub span: Span,
}
impl ResolvedNode for FunctionInputVariableType {
type Error = TypeError;
type UnresolvedNode = FunctionInputVariable;
///
/// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`.
///
/// Performs a lookup in the given symbol table if the type is user-defined.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
let type_ = ExtendedType::resolve(table, (unresolved.type_, unresolved.span.clone()))?;
let attributes = if unresolved.mutable {
vec![Attribute::Mutable]
} else {
vec![]
};
Ok(FunctionInputVariableType {
identifier: unresolved.identifier,
type_,
attributes,
span: unresolved.span,
})
}
}
impl FunctionInputVariableType {
///
/// Return a new `FunctionInputVariableType` from a given `FunctionInputVariable`.
///
/// Performs a lookup in the given symbol table if the type is user-defined.
///
/// If the type of the function return type is the `Self` keyword, then the given circuit
/// identifier is used as the type.
///
pub fn from_circuit(
table: &mut SymbolTable,
unresolved_function_input: FunctionInputVariable,
circuit_name: Identifier,
) -> Result<Self, TypeError> {
let type_ = ExtendedType::from_circuit(
table,
unresolved_function_input.type_,
circuit_name,
unresolved_function_input.span.clone(),
)?;
let attributes = if unresolved_function_input.mutable {
vec![Attribute::Mutable]
} else {
vec![]
};
Ok(FunctionInputVariableType {
identifier: unresolved_function_input.identifier,
type_,
attributes,
span: unresolved_function_input.span,
})
}
///
/// Insert the current function input variable type into the given symbol table.
///
/// If the symbol table did not have this name present, `None` is returned.
///
pub fn insert(&self, table: &mut SymbolTable) -> Option<VariableType> {
let key = self.identifier.name.clone();
let value = VariableType::from(self.clone());
table.insert_variable(key, value)
}
}

View File

@ -1,74 +0,0 @@
// Copyright (C) 2019-2020 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::{ExtendedType, ResolvedNode, SymbolTable, TypeError};
use leo_typed::{Identifier, Span, Type as UnresolvedType};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct FunctionOutputType {
/// Type of function output.
pub type_: ExtendedType,
}
impl ResolvedNode for FunctionOutputType {
type Error = TypeError;
/// (optional function output, span)
type UnresolvedNode = (Option<UnresolvedType>, Span);
///
/// Return a new `FunctionOutputType` from a given optional function return type and span.
///
/// Performs a lookup in the given symbol table if the return type is user-defined.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, TypeError> {
let function_output = unresolved.0;
let span = unresolved.1;
let type_ = match function_output {
None => ExtendedType::Tuple(vec![]), // functions with no return value return an empty tuple
Some(type_) => ExtendedType::resolve(table, (type_, span))?,
};
Ok(FunctionOutputType { type_ })
}
}
impl FunctionOutputType {
///
/// Return a new `FunctionOutputType` from a given optional function return type and span.
///
/// Performs a lookup in the given symbol table if the return type is user-defined.
///
/// If the type of the function return type is the `Self` keyword, then the given circuit
/// identifier is used as the type.
///
pub fn from_circuit(
table: &mut SymbolTable,
circuit_name: Identifier,
unresolved: Option<UnresolvedType>,
span: Span,
) -> Result<Self, TypeError> {
let output_type = match unresolved {
None => ExtendedType::Tuple(vec![]),
Some(type_) => ExtendedType::from_circuit(table, type_, circuit_name, span)?,
};
Ok(FunctionOutputType { type_: output_type })
}
}

View File

@ -1,27 +0,0 @@
// Copyright (C) 2019-2020 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/>.
pub mod circuits;
pub use self::circuits::*;
pub mod functions;
pub use self::functions::*;
pub mod type_;
pub use self::type_::*;
pub mod variables;
pub use self::variables::*;

View File

@ -1,221 +0,0 @@
// Copyright (C) 2019-2020 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::{ResolvedNode, SymbolTable, TypeError};
use leo_typed::{Identifier, IntegerType, Span, Type as UnresolvedType};
use serde::{Deserialize, Serialize};
use std::fmt;
/// A resolved type in a Leo program.
///
/// This type cannot be an implicit or `Self` type.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ExtendedType {
// Data types
Address,
Boolean,
Field,
Group,
IntegerType(IntegerType),
// Data type wrappers
Array(Box<ExtendedType>, Vec<usize>),
Tuple(Vec<ExtendedType>),
// User defined types
Circuit(Identifier),
Function(Identifier),
}
impl ResolvedNode for ExtendedType {
type Error = TypeError;
type UnresolvedNode = (UnresolvedType, Span);
///
/// Resolves the given type.
///
/// Cannot be an implicit or `Self` type.
///
fn resolve(table: &mut SymbolTable, unresolved: Self::UnresolvedNode) -> Result<Self, Self::Error> {
let type_ = unresolved.0;
let span = unresolved.1;
Ok(match type_ {
UnresolvedType::Address => ExtendedType::Address,
UnresolvedType::Boolean => ExtendedType::Boolean,
UnresolvedType::Field => ExtendedType::Field,
UnresolvedType::Group => ExtendedType::Group,
UnresolvedType::IntegerType(integer) => ExtendedType::IntegerType(integer),
UnresolvedType::Array(type_, dimensions) => {
let array_type = ExtendedType::resolve(table, (*type_, span))?;
ExtendedType::Array(Box::new(array_type), dimensions)
}
UnresolvedType::Tuple(types) => {
let tuple_types = types
.into_iter()
.map(|type_| ExtendedType::resolve(table, (type_, span.clone())))
.collect::<Result<Vec<_>, _>>()?;
ExtendedType::Tuple(tuple_types)
}
UnresolvedType::Circuit(identifier) => {
// Lookup the circuit type in the symbol table
let circuit_type = table
.get_circuit(&identifier.name)
.ok_or(TypeError::undefined_circuit(identifier))?;
ExtendedType::Circuit(circuit_type.identifier.clone())
}
UnresolvedType::SelfType => {
// Throw an error for using `Self` outside of a circuit
return Err(TypeError::self_not_available(span));
}
})
}
}
impl ExtendedType {
///
/// Resolve a type inside of a circuit definition.
///
/// If this type is SelfType, return the circuit's type.
///
pub fn from_circuit(
table: &mut SymbolTable,
type_: UnresolvedType,
circuit_name: Identifier,
span: Span,
) -> Result<Self, TypeError> {
Ok(match type_ {
UnresolvedType::Array(type_, dimensions) => {
let array_type = ExtendedType::from_circuit(table, *type_, circuit_name, span)?;
ExtendedType::Array(Box::new(array_type), dimensions)
}
UnresolvedType::Tuple(types) => {
let tuple_types = types
.into_iter()
.map(|type_| ExtendedType::from_circuit(table, type_, circuit_name.clone(), span.clone()))
.collect::<Result<Vec<_>, _>>()?;
ExtendedType::Tuple(tuple_types)
}
UnresolvedType::SelfType => ExtendedType::Circuit(circuit_name),
// The unresolved type does not depend on the current circuit definition
unresolved => ExtendedType::resolve(table, (unresolved, span))?,
})
}
///
/// Returns `Ok` if the given expected type is `Some` and expected type == actual type.
///
pub fn check_type(expected_option: &Option<Self>, actual: &ExtendedType, span: Span) -> Result<(), TypeError> {
if let Some(expected) = expected_option {
if expected.ne(actual) {
return Err(TypeError::mismatched_types(expected, actual, span));
}
}
Ok(())
}
///
/// Returns `Ok` if self is an expected integer type `Type::IntegerType`.
///
pub fn check_type_integer(&self, span: Span) -> Result<(), TypeError> {
match self {
ExtendedType::IntegerType(_) => Ok(()),
// Throw mismatched type error
type_ => Err(TypeError::invalid_integer(type_, span)),
}
}
///
/// Returns array element type and dimensions if self is an expected array type `Type::Array`.
///
pub fn get_type_array(&self, span: Span) -> Result<(&ExtendedType, &Vec<usize>), TypeError> {
match self {
ExtendedType::Array(element_type, dimensions) => Ok((element_type, dimensions)),
// Throw mismatched type error
type_ => Err(TypeError::invalid_array(type_, span)),
}
}
///
/// Returns tuple element types if self is an expected tuple type `Type::Tuple`.
///
pub fn get_type_tuple(&self, span: Span) -> Result<&Vec<ExtendedType>, TypeError> {
match self {
ExtendedType::Tuple(types) => Ok(types),
// Throw mismatched type error
type_ => Err(TypeError::invalid_tuple(type_, span)),
}
}
///
/// Returns circuit identifier if self is an expected circuit type `Type::Circuit`.
///
pub fn get_type_circuit(&self, span: Span) -> Result<&Identifier, TypeError> {
match self {
ExtendedType::Circuit(identifier) => Ok(identifier),
// Throw mismatched type error
type_ => Err(TypeError::invalid_circuit(type_, span)),
}
}
///
/// Returns function identifier if self is an expected function type `Type::Function`.
///
pub fn get_type_function(&self, span: Span) -> Result<&Identifier, TypeError> {
match self {
ExtendedType::Function(identifier) => Ok(identifier),
// Throw mismatched type error
type_ => Err(TypeError::invalid_function(type_, span)),
}
}
}
impl fmt::Display for ExtendedType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
ExtendedType::Address => write!(f, "address"),
ExtendedType::Boolean => write!(f, "bool"),
ExtendedType::Field => write!(f, "field"),
ExtendedType::Group => write!(f, "group"),
ExtendedType::IntegerType(integer_type) => write!(f, "{}", integer_type),
ExtendedType::Array(type_, dimensions) => {
let dimensions_string = dimensions
.iter()
.map(|dimension| format!("{}", dimension))
.collect::<Vec<_>>()
.join(", ");
write!(f, "[{}; ({})]", *type_, dimensions_string)
}
ExtendedType::Tuple(tuple) => {
let tuple_string = tuple.iter().map(|x| format!("{}", x)).collect::<Vec<_>>().join(", ");
write!(f, "({})", tuple_string)
}
ExtendedType::Circuit(identifier) => write!(f, "circuit {}", identifier),
ExtendedType::Function(identifier) => write!(f, "function {}", identifier),
}
}
}

View File

@ -1,18 +0,0 @@
// Copyright (C) 2019-2020 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/>.
pub mod variable;
pub use self::variable::*;

View File

@ -1,79 +0,0 @@
// Copyright (C) 2019-2020 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::{Attribute, ExtendedType};
use leo_typed::{Circuit, Function, Identifier};
use crate::FunctionInputVariableType;
use std::fmt;
/// Stores variable definition details.
///
/// This type should be added to the variable symbol table for a resolved syntax tree.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct VariableType {
pub identifier: Identifier,
pub type_: ExtendedType,
pub attributes: Vec<Attribute>,
}
impl VariableType {
///
/// Returns `true` if this variable's value can be modified.
///
pub fn is_mutable(&self) -> bool {
self.attributes.contains(&Attribute::Mutable)
}
}
impl From<Circuit> for VariableType {
fn from(value: Circuit) -> Self {
let identifier = value.circuit_name;
VariableType {
identifier: identifier.clone(),
type_: ExtendedType::Circuit(identifier),
attributes: vec![],
}
}
}
impl From<Function> for VariableType {
fn from(value: Function) -> Self {
let identifier = value.identifier;
VariableType {
identifier: identifier.clone(),
type_: ExtendedType::Function(identifier.clone()),
attributes: vec![],
}
}
}
impl From<FunctionInputVariableType> for VariableType {
fn from(value: FunctionInputVariableType) -> Self {
VariableType {
identifier: value.identifier,
type_: value.type_,
attributes: value.attributes,
}
}
}
impl fmt::Display for VariableType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.identifier)
}
}

View File

@ -1,36 +0,0 @@
[package]
name = "leo-types"
version = "1.0.3"
authors = [ "The Aleo Team <hello@aleo.org>" ]
description = "Leo program type and type variables"
homepage = "https://aleo.org"
respository = "https://github.com/AleoHQ/leo"
keywords = [
"aleo",
"cryptography",
"leo",
"programming-language",
"zero-knowledge"
]
categories = [ "cryptography::croptocurrencies", "web-programming" ]
include = [ "Cargo.toml", "src", "README.md", "LICENSE.md" ]
license = "GPL-3.0"
edition = "2018"
[dependencies.leo-ast]
path = "../ast"
version = "1.0.3"
[dependencies.leo-imports]
path = "../imports"
version = "1.0.3"
[dependencies.leo-typed]
path = "../typed"
version = "1.0.3"
[dependencies.serde]
version = "1.0"
[dependencies.thiserror]
version = "1.0"

View File

@ -1,24 +0,0 @@
// Copyright (C) 2019-2020 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 serde::{Deserialize, Serialize};
/// Indicates that a program variable has additional functionality.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Attribute {
Mutable,
Static,
}

View File

@ -1,18 +0,0 @@
// Copyright (C) 2019-2020 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/>.
pub mod attribute;
pub use self::attribute::*;

View File

@ -1,21 +0,0 @@
// Copyright (C) 2019-2020 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/>.
pub mod symbol_table;
pub use self::symbol_table::*;
pub mod type_;
pub use self::type_::*;

View File

@ -1,67 +0,0 @@
// Copyright (C) 2019-2020 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::TypeError;
use leo_typed::{Error as FormattedError, Identifier, Span};
use std::path::PathBuf;
/// Errors encountered when tracking variable, function, and circuit names in a program
#[derive(Debug, Error)]
pub enum SymbolTableError {
#[error("{}", _0)]
Error(#[from] FormattedError),
#[error("{}", _0)]
TypeError(#[from] TypeError),
}
impl SymbolTableError {
///
/// Set the filepath for the error stacktrace
///
pub fn set_path(&mut self, path: PathBuf) {
match self {
SymbolTableError::Error(error) => error.set_path(path),
SymbolTableError::TypeError(error) => error.set_path(path),
}
}
///
/// Return a new formatted error with a given message and span information
///
fn new_from_span(message: String, span: Span) -> Self {
SymbolTableError::Error(FormattedError::new_from_span(message, span))
}
///
/// Two circuits have been defined with the same name
///
pub fn duplicate_circuit(identifier: Identifier, span: Span) -> Self {
let message = format!("Duplicate circuit definition found for `{}`", identifier);
Self::new_from_span(message, span)
}
///
/// Two functions have been defined with the same name
///
pub fn duplicate_function(identifier: Identifier, span: Span) -> Self {
let message = format!("Duplicate function definition found for `{}`", identifier);
Self::new_from_span(message, span)
}
}

View File

@ -1,27 +0,0 @@
// Copyright (C) 2019-2020 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::{types::FunctionType, Attribute};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CircuitFunctionType {
/// The function signature of the circuit function
pub function: FunctionType,
/// The attributes of the circuit function
pub attributes: Vec<Attribute>,
}

View File

@ -1,24 +0,0 @@
// Copyright (C) 2019-2020 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/>.
pub mod circuit;
pub use self::circuit::*;
pub mod circuit_function;
pub use self::circuit_function::*;
pub mod circuit_variable;
pub use self::circuit_variable::*;

View File

@ -1,27 +0,0 @@
// Copyright (C) 2019-2020 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/>.
pub mod function;
pub use self::function::*;
pub mod function_input;
pub use self::function_input::*;
pub mod function_input_variable;
pub use self::function_input_variable::*;
pub mod function_output;
pub use self::function_output::*;