mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-18 23:02:35 +03:00
statements almost done, iteration statements causing issues
This commit is contained in:
parent
4612602807
commit
d39ee31933
@ -76,9 +76,7 @@ impl<'a, V: ExpressionVisitor<'a>> VisitorDirector<'a, V> {
|
|||||||
|
|
||||||
pub fn visit_call(&mut self, input: &'a CallExpression) {
|
pub fn visit_call(&mut self, input: &'a CallExpression) {
|
||||||
if let VisitResult::VisitChildren = self.visitor.visit_call(input) {
|
if let VisitResult::VisitChildren = self.visitor.visit_call(input) {
|
||||||
for expr in input.arguments.iter() {
|
input.arguments.iter().for_each(|expr| self.visit_expression(expr));
|
||||||
self.visit_expression(expr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,8 +135,11 @@ impl<'a, V: ExpressionVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V>
|
|||||||
|
|
||||||
pub fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
pub fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
||||||
if let VisitResult::VisitChildren = self.visitor.visit_console(input) {
|
if let VisitResult::VisitChildren = self.visitor.visit_console(input) {
|
||||||
if let ConsoleFunction::Assert(expr) = &input.function {
|
match &input.function {
|
||||||
self.visit_expression(expr);
|
ConsoleFunction::Assert(expr) => self.visit_expression(expr),
|
||||||
|
ConsoleFunction::Error(fmt) | ConsoleFunction::Log(fmt) => {
|
||||||
|
fmt.parameters.iter().for_each(|expr| self.visit_expression(expr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,9 +152,7 @@ impl<'a, V: ExpressionVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V>
|
|||||||
|
|
||||||
pub fn visit_block(&mut self, input: &'a Block) {
|
pub fn visit_block(&mut self, input: &'a Block) {
|
||||||
if let VisitResult::VisitChildren = self.visitor.visit_block(input) {
|
if let VisitResult::VisitChildren = self.visitor.visit_block(input) {
|
||||||
for stmt in input.statements.iter() {
|
input.statements.iter().for_each(|stmt| self.visit_statement(stmt));
|
||||||
self.visit_statement(stmt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,9 +160,10 @@ impl<'a, V: ExpressionVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V>
|
|||||||
impl<'a, V: ExpressionVisitor<'a> + ProgramVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V> {
|
impl<'a, V: ExpressionVisitor<'a> + ProgramVisitor<'a> + StatementVisitor<'a>> VisitorDirector<'a, V> {
|
||||||
pub fn visit_program(&mut self, input: &'a Program) {
|
pub fn visit_program(&mut self, input: &'a Program) {
|
||||||
if let VisitResult::VisitChildren = self.visitor.visit_program(input) {
|
if let VisitResult::VisitChildren = self.visitor.visit_program(input) {
|
||||||
for function in input.functions.values() {
|
input
|
||||||
self.visit_function(function);
|
.functions
|
||||||
}
|
.values()
|
||||||
|
.for_each(|function| self.visit_function(function));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,21 @@ impl<'a> SymbolTable<'a> {
|
|||||||
pub fn lookup_var(&self, symbol: &Symbol) -> Option<&&'a DefinitionStatement> {
|
pub fn lookup_var(&self, symbol: &Symbol) -> Option<&&'a DefinitionStatement> {
|
||||||
self.variables.variables.get(symbol)
|
self.variables.variables.get(symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn push_variable_scope(&mut self) {
|
||||||
|
let current_scope = self.variables.clone();
|
||||||
|
self.variables = VariableSymbol {
|
||||||
|
parent: Some(Box::new(current_scope)),
|
||||||
|
inputs: Default::default(),
|
||||||
|
variables: Default::default(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop_variable_scope(&mut self) {
|
||||||
|
let parent = self.variables.parent.clone().unwrap();
|
||||||
|
|
||||||
|
self.variables = *parent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Display for SymbolTable<'a> {
|
impl<'a> Display for SymbolTable<'a> {
|
||||||
|
@ -34,6 +34,17 @@ impl<'a> TypeChecker<'a> {
|
|||||||
self.handler.emit_err(err1);
|
self.handler.emit_err(err1);
|
||||||
self.handler.emit_err(err2);
|
self.handler.emit_err(err2);
|
||||||
}
|
}
|
||||||
|
// Types match
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_type(&self, type_: Result<Option<Type>>, expected: Type, span: &Span) {
|
||||||
|
match type_ {
|
||||||
|
Ok(Some(type_)) if type_ != expected => self
|
||||||
|
.handler
|
||||||
|
.emit_err(TypeCheckerError::type_should_be(type_, expected, span).into()),
|
||||||
|
// Types match
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,27 +114,58 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Default::default()
|
VisitResult::VisitChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_conditional(&mut self, _input: &'a ConditionalStatement) -> VisitResult {
|
fn visit_conditional(&mut self, input: &'a ConditionalStatement) -> VisitResult {
|
||||||
Default::default()
|
self.assert_type(input.condition.get_type(), Type::Boolean, input.span());
|
||||||
|
|
||||||
|
VisitResult::VisitChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_iteration(&mut self, _input: &'a IterationStatement) -> VisitResult {
|
fn visit_iteration(&mut self, input: &'a IterationStatement) -> VisitResult {
|
||||||
Default::default()
|
// TODO: need to change symbol table to some other repr for variables.
|
||||||
|
// self.symbol_table.insert_variable(input.variable.name, input);
|
||||||
|
|
||||||
|
let iter_var_type = input.get_type();
|
||||||
|
|
||||||
|
self.compare_types(iter_var_type.clone(), input.start.get_type(), input.span());
|
||||||
|
self.compare_types(iter_var_type, input.stop.get_type(), input.span());
|
||||||
|
|
||||||
|
VisitResult::VisitChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_console(&mut self, _input: &'a ConsoleStatement) -> VisitResult {
|
fn visit_console(&mut self, input: &'a ConsoleStatement) -> VisitResult {
|
||||||
Default::default()
|
match &input.function {
|
||||||
|
ConsoleFunction::Assert(expr) => {
|
||||||
|
self.assert_type(expr.get_type(), Type::Boolean, expr.span());
|
||||||
|
}
|
||||||
|
ConsoleFunction::Error(_) | ConsoleFunction::Log(_) => {
|
||||||
|
todo!("need to discuss this");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_expression_statement(&mut self, _input: &'a ExpressionStatement) -> VisitResult {
|
VisitResult::VisitChildren
|
||||||
Default::default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_block(&mut self, _input: &'a Block) -> VisitResult {
|
fn visit_block(&mut self, input: &'a Block) -> VisitResult {
|
||||||
Default::default()
|
self.symbol_table.push_variable_scope();
|
||||||
|
// have to redo the logic here so we have scoping
|
||||||
|
input.statements.iter().for_each(|stmt| {
|
||||||
|
match stmt {
|
||||||
|
Statement::Return(stmt) => self.visit_return(stmt),
|
||||||
|
Statement::Definition(stmt) => self.visit_definition(stmt),
|
||||||
|
Statement::Assign(stmt) => self.visit_assign(stmt),
|
||||||
|
Statement::Conditional(stmt) => self.visit_conditional(stmt),
|
||||||
|
Statement::Iteration(stmt) => self.visit_iteration(stmt),
|
||||||
|
Statement::Console(stmt) => self.visit_console(stmt),
|
||||||
|
Statement::Expression(stmt) => self.visit_expression_statement(stmt),
|
||||||
|
Statement::Block(stmt) => self.visit_block(stmt),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
self.symbol_table.pop_variable_scope();
|
||||||
|
|
||||||
|
VisitResult::SkipChildren
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,4 +72,14 @@ create_messages!(
|
|||||||
),
|
),
|
||||||
help: None,
|
help: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For when the user tries to assign to a const input.
|
||||||
|
@formatted
|
||||||
|
type_should_be {
|
||||||
|
args: (type_: impl Display, expected: impl Display),
|
||||||
|
msg: format!(
|
||||||
|
"Found type `{type_}` but type `{expected}` was expected",
|
||||||
|
),
|
||||||
|
help: None,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user