Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
cburgdorf committed Feb 4, 2021
1 parent 013787a commit 883bf53
Show file tree
Hide file tree
Showing 17 changed files with 609 additions and 26 deletions.
21 changes: 15 additions & 6 deletions analyzer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::namespace::scopes::{
use crate::namespace::types::{
Contract,
FixedSize,
Struct,
Type,
};
use fe_parser::ast as fe;
Expand Down Expand Up @@ -55,6 +56,7 @@ impl Location {
Type::Array(_) => Ok(Location::Memory),
Type::Tuple(_) => Ok(Location::Memory),
Type::String(_) => Ok(Location::Memory),
Type::Struct(_) => Ok(Location::Memory),
Type::Map(_) => Err(SemanticError::cannot_move()),
}
}
Expand All @@ -71,6 +73,8 @@ pub struct ContractAttributes {
pub events: Vec<Event>,
/// Static strings that the contract defines
pub string_literals: HashSet<String>,
/// Structs that have been defined by the user
pub structs: Vec<Struct>,
/// External contracts that may be called from within this contract.
pub external_contracts: Vec<Contract>,
}
Expand Down Expand Up @@ -108,6 +112,14 @@ impl From<Shared<ContractScope>> for ContractAttributes {
}
});

let structs = scope.borrow().get_module_type_defs(|typ| {
if let Type::Struct(val) = typ {
Some(val.to_owned())
} else {
None
}
});

ContractAttributes {
public_functions,
init_function,
Expand All @@ -118,6 +130,7 @@ impl From<Shared<ContractScope>> for ContractAttributes {
.map(|event| event.to_owned())
.collect::<Vec<Event>>(),
string_literals: scope.borrow().string_defs.clone(),
structs,
external_contracts,
}
}
Expand Down Expand Up @@ -248,12 +261,8 @@ impl Context {
}

/// Attribute contextual information to an expression node.
pub fn add_expression(
&mut self,
spanned: &Spanned<fe::Expr>,
attributes: ExpressionAttributes,
) {
self.expressions.insert(spanned.span, attributes);
pub fn add_expression<T: Into<Span>>(&mut self, span: T, attributes: ExpressionAttributes) {
self.expressions.insert(span.into(), attributes);
}

/// Get information that has been attributed to an expression node.
Expand Down
1 change: 1 addition & 0 deletions analyzer/src/namespace/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub fn index(value: Type, index: Type) -> Result<Type, SemanticError> {
Type::Tuple(_) => Err(SemanticError::not_subscriptable()),
Type::String(_) => Err(SemanticError::not_subscriptable()),
Type::Contract(_) => Err(SemanticError::not_subscriptable()),
Type::Struct(_) => Err(SemanticError::not_subscriptable()),
}
}

Expand Down
72 changes: 70 additions & 2 deletions analyzer/src/namespace/types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use crate::errors::SemanticError;
use fe_parser::ast as fe;
use std::collections::HashMap;
use fe::StructStmt;
use fe_parser::{
ast as fe,
span::Spanned,
};
use std::collections::{
BTreeMap,
HashMap,
};
use std::convert::TryFrom;
use std::num::{
IntErrorKind,
Expand Down Expand Up @@ -103,6 +110,7 @@ pub enum Type {
Tuple(Tuple),
String(FeString),
Contract(Contract),
Struct(Struct),
}

#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
Expand All @@ -112,6 +120,7 @@ pub enum FixedSize {
Tuple(Tuple),
String(FeString),
Contract(Contract),
Struct(Struct),
}

#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
Expand Down Expand Up @@ -157,6 +166,12 @@ pub struct Tuple {
pub items: Vec<Base>,
}

#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
pub struct Struct {
pub name: String,
pub fields: BTreeMap<String, Base>,
}

#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq)]
pub struct FeString {
pub max_size: usize,
Expand All @@ -168,6 +183,33 @@ pub struct Contract {
pub functions: Vec<FunctionAttributes>,
}

impl Struct {
pub fn new(name: &str) -> Struct {
Struct {
name: name.to_string(),
fields: BTreeMap::new(),
}
}
}

pub fn to_struct(
name: &str,
struct_stmts: &[Spanned<StructStmt>],
defs: &HashMap<String, Type>,
) -> Result<Type, SemanticError> {
let mut val = Struct::new(name);
for stmt in struct_stmts {
let StructStmt::StructField { name, typ } = &stmt.node;
let field_type = type_desc(defs, &typ.node)?;
if let Type::Base(base_typ) = field_type {
val.fields.insert(name.node.to_string(), base_typ);
} else {
unimplemented!("Fields can only be base types at this point")
}
}
Ok(Type::Struct(val))
}

impl TryFrom<&str> for FeString {
type Error = String;

Expand Down Expand Up @@ -258,6 +300,7 @@ impl From<FixedSize> for Type {
FixedSize::Tuple(tuple) => Type::Tuple(tuple),
FixedSize::String(string) => Type::String(string),
FixedSize::Contract(contract) => Type::Contract(contract),
FixedSize::Struct(val) => Type::Struct(val),
}
}
}
Expand All @@ -270,6 +313,7 @@ impl FeSized for FixedSize {
FixedSize::Tuple(tuple) => tuple.size(),
FixedSize::String(string) => string.size(),
FixedSize::Contract(contract) => contract.size(),
FixedSize::Struct(val) => val.size(),
}
}
}
Expand Down Expand Up @@ -301,6 +345,7 @@ impl AbiEncoding for FixedSize {
FixedSize::Tuple(tuple) => tuple.abi_name(),
FixedSize::String(string) => string.abi_name(),
FixedSize::Contract(contract) => contract.abi_name(),
FixedSize::Struct(val) => val.abi_name(),
}
}

Expand All @@ -311,6 +356,7 @@ impl AbiEncoding for FixedSize {
FixedSize::Tuple(tuple) => tuple.abi_safe_name(),
FixedSize::String(string) => string.abi_safe_name(),
FixedSize::Contract(contract) => contract.abi_safe_name(),
FixedSize::Struct(val) => val.abi_safe_name(),
}
}

Expand All @@ -321,6 +367,7 @@ impl AbiEncoding for FixedSize {
FixedSize::Tuple(tuple) => tuple.abi_type(),
FixedSize::String(string) => string.abi_type(),
FixedSize::Contract(contract) => contract.abi_type(),
FixedSize::Struct(val) => val.abi_type(),
}
}
}
Expand Down Expand Up @@ -348,6 +395,7 @@ impl TryFrom<Type> for FixedSize {
Type::Base(base) => Ok(FixedSize::Base(base)),
Type::Tuple(tuple) => Ok(FixedSize::Tuple(tuple)),
Type::String(string) => Ok(FixedSize::String(string)),
Type::Struct(val) => Ok(FixedSize::Struct(val)),
Type::Map(_) => Err(SemanticError::type_error()),
Type::Contract(contract) => Ok(FixedSize::Contract(contract)),
}
Expand Down Expand Up @@ -543,6 +591,26 @@ impl FeSized for Tuple {
}
}

impl FeSized for Struct {
fn size(&self) -> usize {
self.fields.values().map(|val| val.size()).sum()
}
}

impl AbiEncoding for Struct {
fn abi_name(&self) -> String {
unimplemented!();
}

fn abi_safe_name(&self) -> String {
unimplemented!();
}

fn abi_type(&self) -> AbiType {
unimplemented!();
}
}

impl AbiEncoding for Tuple {
fn abi_name(&self) -> String {
unimplemented!();
Expand Down
1 change: 0 additions & 1 deletion analyzer/src/traversal/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ pub fn var_decl(
return Err(SemanticError::type_error());
}
}

scope.borrow_mut().add_var(name, declared_type.clone());
context.borrow_mut().add_declaration(stmt, declared_type);

Expand Down
Loading

0 comments on commit 883bf53

Please sign in to comment.