Skip to content

Commit

Permalink
[untested] resolve var decl
Browse files Browse the repository at this point in the history
  • Loading branch information
SkymanOne committed Mar 18, 2024
1 parent bc6c261 commit 4259fd5
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 34 deletions.
18 changes: 18 additions & 0 deletions crates/parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,21 @@ impl Expression {
}
}
}

impl Statement {
pub fn loc(&self) -> &Span {
match self {
Statement::Variable(v) => &v.loc,
Statement::Assign(a) => &a.loc,
Statement::IfElse(br) => &br.loc,
Statement::ForLoop(l) => &l.loc,
Statement::Iterator(i) => &i.loc,
Statement::Return(e) => e.loc(),
Statement::Expression(e) => e.loc(),
Statement::StateTransition(tr) => &tr.loc,
Statement::Block(b) => &b.loc,
Statement::Skip(s) => s,
Statement::Error(s) => s,
}
}
}
7 changes: 5 additions & 2 deletions crates/semantics/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ pub struct Variable {
pub loc: Span,
pub names: Vec<Identifier>,
pub mutable: bool,
pub ty: Option<Type>,
pub ty: TypeVariant,
pub value: Option<Expression>,
}

Expand Down Expand Up @@ -368,11 +368,14 @@ pub struct Iterator {

#[derive(Clone, Debug, PartialEq, Node)]
pub struct StructInit {
pub loc: Span,
pub name: Identifier,
pub args: Vec<Expression>,
/// Autofill fields from partial object
/// using `..ident` notation.
pub auto_object: Option<Identifier>,
/// Type of an expression.
pub ty: TypeVariant,
}

#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -413,7 +416,7 @@ pub enum Expression {

FunctionCall(FunctionCall),
MemberAccess(MemberAccess),
StructInit(UnaryExpression<StructInit>),
StructInit(StructInit),

List(UnaryExpression<Vec<Expression>>),
}
Expand Down
44 changes: 17 additions & 27 deletions crates/semantics/src/expression/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ use folidity_parser::{
ast::{
self as parsed_ast,
Identifier,
Type,
},
Span,
};

use crate::{
ast::{
self,
BinaryExpression,
Expression,
Function,
FunctionCall,
Expand Down Expand Up @@ -614,7 +612,7 @@ pub fn resolve_struct_init(
Ok(parsed_args)
};

let mut check_types = |tv: TypeVariant, contract: &mut ContractDefinition| -> Result<(), ()> {
let check_types = |tv: TypeVariant, contract: &mut ContractDefinition| -> Result<(), ()> {
match &expected_ty {
ExpectedType::Empty => {
contract.diagnostics.push(Report::type_error(
Expand Down Expand Up @@ -657,13 +655,11 @@ pub fn resolve_struct_init(
return Err(());
}

Ok(Expression::StructInit(UnaryExpression {
Ok(Expression::StructInit(StructInit {
loc: loc.clone(),
element: StructInit {
name: ident.clone(),
args: parsed_args,
auto_object: None,
},
name: ident.clone(),
args: parsed_args,
auto_object: None,
ty: TypeVariant::Struct(s.clone()),
}))
}
Expand All @@ -672,13 +668,11 @@ pub fn resolve_struct_init(

let parsed_args = resolve_model(&s, contract)?;

Ok(Expression::StructInit(UnaryExpression {
Ok(Expression::StructInit(StructInit {
loc: loc.clone(),
element: StructInit {
name: ident.clone(),
args: parsed_args,
auto_object: None,
},
name: ident.clone(),
args: parsed_args,
auto_object: None,
ty: TypeVariant::Model(s.clone()),
}))
}
Expand All @@ -694,13 +688,11 @@ pub fn resolve_struct_init(
));
return Err(());
} else {
return Ok(Expression::StructInit(UnaryExpression {
return Ok(Expression::StructInit(StructInit {
loc: loc.clone(),
element: StructInit {
name: ident.clone(),
args: vec![],
auto_object: None,
},
name: ident.clone(),
args: vec![],
auto_object: None,
ty: TypeVariant::State(s.clone()),
}));
};
Expand Down Expand Up @@ -729,13 +721,11 @@ pub fn resolve_struct_init(
}
StateBody::Model(s) => resolve_model(s, contract)?,
};
Ok(Expression::StructInit(UnaryExpression {
Ok(Expression::StructInit(StructInit {
loc: loc.clone(),
element: StructInit {
name: ident.clone(),
args: parsed_args,
auto_object: None,
},
name: ident.clone(),
args: parsed_args,
auto_object: None,
ty: TypeVariant::State(s.clone()),
}))
}
Expand Down
2 changes: 1 addition & 1 deletion crates/semantics/src/expression/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,5 +717,5 @@ fn init_struct() {
.unwrap()
})
.collect();
assert_eq!(init.element.args, resolved_args)
assert_eq!(init.args, resolved_args)
}
94 changes: 94 additions & 0 deletions crates/semantics/src/statement.rs
Original file line number Diff line number Diff line change
@@ -1 +1,95 @@
use folidity_diagnostics::Report;
use folidity_parser::ast as parsed_ast;

use crate::{
ast::{
Statement,
Variable,
},
contract::ContractDefinition,
expression::expression,
symtable::{
Scope,
VariableKind,
},
types::{
map_type,
ExpectedType,
},
};

/// Resolve parsed statement to an evaluated one.
pub fn statement(
stmt: &parsed_ast::Statement,
resolved: &mut Vec<Statement>,
scope: &mut Scope,
contract: &mut ContractDefinition,
) -> Result<bool, ()> {
match stmt {
parsed_ast::Statement::Variable(var) => {
let (expr, ty) = match (&var.value, &var.ty) {
(Some(e), Some(ty)) => {
let tv = map_type(contract, ty)?.ty;
(
Some(expression(
e,
ExpectedType::Concrete(tv.clone()),
scope,
contract,
)?),
tv,
)
}
(Some(e), None) => {
let resolved = expression(e, ExpectedType::Dynamic(vec![]), scope, contract)?;
let ty = resolved.ty().clone();
(Some(resolved), ty)
}
(None, Some(ty)) => {
let tv = map_type(contract, ty)?;
(None, tv.ty)
}
_ => {
contract.diagnostics.push(Report::type_error(stmt.loc().clone(), String::from("Type can not be inferred. Try annotating the variable or providing and expression.")));
return Err(());
}
};

// todo: destructure fields.
if var.names.len() != 1 {
contract.diagnostics.push(Report::semantic_error(
stmt.loc().clone(),
String::from("Destructuring is currently unsupported."),
));
return Err(());
}

scope.symbols.add(
contract,
&var.names[0].clone(),
ty.clone(),
expr.clone(),
VariableKind::Local,
);

resolved.push(Statement::Variable(Variable {
loc: var.loc.clone(),
names: var.names.clone(),
mutable: var.mutable,
ty,
value: expr,
}));
Ok(true)
}
parsed_ast::Statement::Assign(_) => todo!(),
parsed_ast::Statement::IfElse(_) => todo!(),
parsed_ast::Statement::ForLoop(_) => todo!(),
parsed_ast::Statement::Iterator(_) => todo!(),
parsed_ast::Statement::Return(_) => todo!(),
parsed_ast::Statement::Expression(_) => todo!(),
parsed_ast::Statement::StateTransition(_) => todo!(),
parsed_ast::Statement::Skip(_) => todo!(),
parsed_ast::Statement::Block(_) => todo!(),
parsed_ast::Statement::Error(_) => todo!(),
}
}
8 changes: 4 additions & 4 deletions crates/semantics/src/symtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ pub enum VariableKind {
Param,
Local,
State,
/// A user defined type
/// (e.g. Struct, Model, Enum, Function)
/// which should exist in global namespace.
User(usize),
// /// A user defined type
// /// (e.g. Struct, Model, Enum, Function)
// /// which should exist in global namespace.
// User(usize),
}

/// Context of the scope in the symtable.
Expand Down

0 comments on commit 4259fd5

Please sign in to comment.