From f868c860f62afec6c1801fe10b910bfd6aa748c5 Mon Sep 17 00:00:00 2001 From: Glyphack Date: Sat, 5 Aug 2023 22:39:50 +0200 Subject: [PATCH 1/3] Refactor symbol table strcture to support nested scopes --- typechecker/src/semantic_analyzer.rs | 17 +- ...echecker__build__tests__assign_stmt-2.snap | 97 ++++---- ...echecker__build__tests__assign_stmt-3.snap | 215 +++++++++--------- ...echecker__build__tests__assign_stmt-4.snap | 93 ++++---- ...echecker__build__tests__assign_stmt-5.snap | 11 +- ...ypechecker__build__tests__assign_stmt.snap | 73 +++--- typechecker/src/symbol_table.rs | 69 ++++-- 7 files changed, 326 insertions(+), 249 deletions(-) diff --git a/typechecker/src/semantic_analyzer.rs b/typechecker/src/semantic_analyzer.rs index 27c3d26d..76d0ba69 100644 --- a/typechecker/src/semantic_analyzer.rs +++ b/typechecker/src/semantic_analyzer.rs @@ -1,12 +1,10 @@ -use std::ops::Deref; - use parser::ast::Expression; use crate::{ ast_visitor::TraversalVisitor, nodes::EnderpyFile, symbol_table::{ - Declaration, DeclarationPath, SymbolScope, SymbolTable, SymbolTableNode, Variable, + Declaration, DeclarationPath, Function, SymbolScope, SymbolTable, SymbolTableNode, Variable, }, }; @@ -224,6 +222,19 @@ impl TraversalVisitor for SemanticAnalyzer { } fn visit_function_def(&mut self, f: &parser::ast::FunctionDef) { + let declaration_path = DeclarationPath { + module_name: self.file.module_name.clone(), + node: f.node, + }; + let functionDeclaration = Function { + declaration_path, + scope: self.current_scope(), + is_method: todo!(), + is_generator: todo!(), + return_statements: todo!(), + yeild_statements: todo!(), + raise_statements: todo!(), + }; for stmt in &f.body { self.visit_stmt(&stmt); } diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap index edca698f..1d5d9472 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap @@ -3,62 +3,67 @@ source: typechecker/src/build.rs description: b = a + 1 --- SymbolTable { - symbol_table_type: Module, - symbols: { - "b": SymbolTableNode { - name: "b", - declarations: [ - Variable( - Variable { - declaration_path: DeclarationPath { - module_name: "test", - node: Node { - start: 0, - end: 9, - }, - }, - scope: Global, - type_annotation: None, - inferred_type_source: Some( - BinOp( - BinOp { + scopes: [ + SymbolTableScope { + start_line_number: 0, + symbol_table_type: Module, + symbols: { + "b": SymbolTableNode { + name: "b", + declarations: [ + Variable( + Variable { + declaration_path: DeclarationPath { + module_name: "test", node: Node { - start: 4, + start: 0, end: 9, }, - op: Add, - left: Name( - Name { + }, + scope: Global, + type_annotation: None, + inferred_type_source: Some( + BinOp( + BinOp { node: Node { start: 4, - end: 5, - }, - id: "a", - }, - ), - right: Constant( - Constant { - node: Node { - start: 8, end: 9, }, - value: Int( - "1", + op: Add, + left: Name( + Name { + node: Node { + start: 4, + end: 5, + }, + id: "a", + }, + ), + right: Constant( + Constant { + node: Node { + start: 8, + end: 9, + }, + value: Int( + "1", + ), + }, ), }, ), - }, - ), + ), + is_constant: false, + }, ), - is_constant: false, - }, - ), - ], - module_public: false, - module_hidden: false, - implicit: false, - scope: Global, + ], + module_public: false, + module_hidden: false, + implicit: false, + scope: Global, + }, + }, }, - }, - start_line_number: 0, + ], + all_scopes: [], } diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap index 4e08920d..44b7ea99 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap @@ -3,122 +3,127 @@ source: typechecker/src/build.rs description: "c,d = 1,2" --- SymbolTable { - symbol_table_type: Module, - symbols: { - "c": SymbolTableNode { - name: "c", - declarations: [ - Variable( - Variable { - declaration_path: DeclarationPath { - module_name: "test", - node: Node { - start: 0, - end: 9, - }, - }, - scope: Global, - type_annotation: None, - inferred_type_source: Some( - Tuple( - Tuple { + scopes: [ + SymbolTableScope { + start_line_number: 0, + symbol_table_type: Module, + symbols: { + "d": SymbolTableNode { + name: "d", + declarations: [ + Variable( + Variable { + declaration_path: DeclarationPath { + module_name: "test", node: Node { - start: 6, + start: 0, end: 9, }, - elements: [ - Constant( - Constant { - node: Node { - start: 6, - end: 7, - }, - value: Int( - "1", - ), + }, + scope: Global, + type_annotation: None, + inferred_type_source: Some( + Tuple( + Tuple { + node: Node { + start: 6, + end: 9, }, - ), - Constant( - Constant { - node: Node { - start: 8, - end: 9, - }, - value: Int( - "2", + elements: [ + Constant( + Constant { + node: Node { + start: 6, + end: 7, + }, + value: Int( + "1", + ), + }, ), - }, - ), - ], - }, - ), - ), - is_constant: false, - }, - ), - ], - module_public: false, - module_hidden: false, - implicit: false, - scope: Global, - }, - "d": SymbolTableNode { - name: "d", - declarations: [ - Variable( - Variable { - declaration_path: DeclarationPath { - module_name: "test", - node: Node { - start: 0, - end: 9, + Constant( + Constant { + node: Node { + start: 8, + end: 9, + }, + value: Int( + "2", + ), + }, + ), + ], + }, + ), + ), + is_constant: false, }, - }, - scope: Global, - type_annotation: None, - inferred_type_source: Some( - Tuple( - Tuple { + ), + ], + module_public: false, + module_hidden: false, + implicit: false, + scope: Global, + }, + "c": SymbolTableNode { + name: "c", + declarations: [ + Variable( + Variable { + declaration_path: DeclarationPath { + module_name: "test", node: Node { - start: 6, + start: 0, end: 9, }, - elements: [ - Constant( - Constant { - node: Node { - start: 6, - end: 7, - }, - value: Int( - "1", - ), + }, + scope: Global, + type_annotation: None, + inferred_type_source: Some( + Tuple( + Tuple { + node: Node { + start: 6, + end: 9, }, - ), - Constant( - Constant { - node: Node { - start: 8, - end: 9, - }, - value: Int( - "2", + elements: [ + Constant( + Constant { + node: Node { + start: 6, + end: 7, + }, + value: Int( + "1", + ), + }, ), - }, - ), - ], - }, - ), + Constant( + Constant { + node: Node { + start: 8, + end: 9, + }, + value: Int( + "2", + ), + }, + ), + ], + }, + ), + ), + is_constant: false, + }, ), - is_constant: false, - }, - ), - ], - module_public: false, - module_hidden: false, - implicit: false, - scope: Global, + ], + module_public: false, + module_hidden: false, + implicit: false, + scope: Global, + }, + }, }, - }, - start_line_number: 0, + ], + all_scopes: [], } diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap index efa19177..d9a85c02 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap @@ -3,54 +3,59 @@ source: typechecker/src/build.rs description: "a: int = 1" --- SymbolTable { - symbol_table_type: Module, - symbols: { - "a": SymbolTableNode { - name: "a", - declarations: [ - Variable( - Variable { - declaration_path: DeclarationPath { - module_name: "test", - node: Node { - start: 0, - end: 10, - }, - }, - scope: Global, - type_annotation: Some( - Name( - Name { - node: Node { - start: 3, - end: 6, - }, - id: "int", - }, - ), - ), - inferred_type_source: Some( - Constant( - Constant { + scopes: [ + SymbolTableScope { + start_line_number: 0, + symbol_table_type: Module, + symbols: { + "a": SymbolTableNode { + name: "a", + declarations: [ + Variable( + Variable { + declaration_path: DeclarationPath { + module_name: "test", node: Node { - start: 9, + start: 0, end: 10, }, - value: Int( - "1", - ), }, - ), + scope: Global, + type_annotation: Some( + Name( + Name { + node: Node { + start: 3, + end: 6, + }, + id: "int", + }, + ), + ), + inferred_type_source: Some( + Constant( + Constant { + node: Node { + start: 9, + end: 10, + }, + value: Int( + "1", + ), + }, + ), + ), + is_constant: false, + }, ), - is_constant: false, - }, - ), - ], - module_public: false, - module_hidden: false, - implicit: false, - scope: Global, + ], + module_public: false, + module_hidden: false, + implicit: false, + scope: Global, + }, + }, }, - }, - start_line_number: 0, + ], + all_scopes: [], } diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap index 2160df9f..dec1da2a 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap @@ -3,7 +3,12 @@ source: typechecker/src/build.rs description: a += b --- SymbolTable { - symbol_table_type: Module, - symbols: {}, - start_line_number: 0, + scopes: [ + SymbolTableScope { + start_line_number: 0, + symbol_table_type: Module, + symbols: {}, + }, + ], + all_scopes: [], } diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap index 0ae2a9cb..06a423fe 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap @@ -3,44 +3,49 @@ source: typechecker/src/build.rs description: "a = 'hello world'" --- SymbolTable { - symbol_table_type: Module, - symbols: { - "a": SymbolTableNode { - name: "a", - declarations: [ - Variable( - Variable { - declaration_path: DeclarationPath { - module_name: "test", - node: Node { - start: 0, - end: 17, - }, - }, - scope: Global, - type_annotation: None, - inferred_type_source: Some( - Constant( - Constant { + scopes: [ + SymbolTableScope { + start_line_number: 0, + symbol_table_type: Module, + symbols: { + "a": SymbolTableNode { + name: "a", + declarations: [ + Variable( + Variable { + declaration_path: DeclarationPath { + module_name: "test", node: Node { - start: 4, + start: 0, end: 17, }, - value: Str( - "hello world", - ), }, - ), + scope: Global, + type_annotation: None, + inferred_type_source: Some( + Constant( + Constant { + node: Node { + start: 4, + end: 17, + }, + value: Str( + "hello world", + ), + }, + ), + ), + is_constant: false, + }, ), - is_constant: false, - }, - ), - ], - module_public: false, - module_hidden: false, - implicit: false, - scope: Global, + ], + module_public: false, + module_hidden: false, + implicit: false, + scope: Global, + }, + }, }, - }, - start_line_number: 0, + ], + all_scopes: [], } diff --git a/typechecker/src/symbol_table.rs b/typechecker/src/symbol_table.rs index ca52784f..17f077ee 100644 --- a/typechecker/src/symbol_table.rs +++ b/typechecker/src/symbol_table.rs @@ -3,13 +3,17 @@ use std::collections::HashMap; #[derive(Debug)] pub struct SymbolTable { + // Sub tables are scopes inside the current scope + scopes: Vec, + // When a symbol goes out of scope we save it here to be able to look it up later + all_scopes: Vec, +} + +#[derive(Debug)] +pub struct SymbolTableScope { + pub start_line_number: u8, pub symbol_table_type: SymbolTableType, symbols: HashMap, - pub start_line_number: u8, - // all sub tables have to be valid until the top level scope is valid - // sub_tables: Vec<&'a SymbolTable<'a>>, - // index of current scope in this table where we insert new symbols - // current_scope: u8, } #[derive(Debug)] @@ -38,6 +42,7 @@ pub struct DeclarationPath { #[derive(Debug)] pub enum Declaration { Variable(Box), + Function(Box), } #[derive(Debug)] @@ -49,6 +54,18 @@ pub struct Variable { pub is_constant: bool, } +#[derive(Debug)] +pub struct Function { + pub declaration_path: DeclarationPath, + pub scope: SymbolScope, + pub is_method: bool, + pub is_generator: bool, + pub return_statements: Vec, + pub yeild_statements: Vec, + // helpful to later type check exceptions + pub raise_statements: Vec, +} + #[derive(Debug, Clone, Copy)] pub enum SymbolScope { Global, @@ -59,24 +76,48 @@ pub enum SymbolScope { impl SymbolTable { pub fn new(symbol_table_type: SymbolTableType, start_line_number: u8) -> Self { - SymbolTable { + let global_scope = SymbolTableScope { + start_line_number, symbol_table_type, symbols: HashMap::new(), - start_line_number, + }; + SymbolTable { + scopes: vec![global_scope], + all_scopes: vec![], + } + } + + fn current_scope(&self) -> &SymbolTableScope { + if let Some(scope) = self.scopes.last() { + return &scope; + } else { + panic!("no scopes") } } pub fn lookup_in_scope(&self, name: &str) -> Option<&SymbolTableNode> { - return self.symbols.get(name); + let cur_scope = self.current_scope(); + return cur_scope.symbols.get(name); + } + + pub fn enter_scope(&mut self, new_scope: SymbolTableScope) { + self.scopes.push(new_scope); } - // - // pub fn enter_scope(&mut self, new_symbol_table: &'a SymbolTable<'a>) { - // self.sub_tables.push(new_symbol_table); - // } - pub fn exit_scope(&self) {} + pub fn exit_scope(&mut self) { + let finished_scope = self.scopes.pop(); + match finished_scope { + Some(scope) => self.all_scopes.push(scope), + None => panic!("tried to exit non-existent scope"), + } + } pub fn add_symbol(&mut self, symbol_node: SymbolTableNode) { - self.symbols.insert(symbol_node.name.clone(), symbol_node); + match self.scopes.last_mut() { + Some(scope) => { + scope.symbols.insert(symbol_node.name.clone(), symbol_node); + } + None => panic!("no current scope, there must be a global scope"), + }; } } From 17f80be71494bc21ea183135df32e9244e37431c Mon Sep 17 00:00:00 2001 From: Glyphack Date: Sun, 6 Aug 2023 17:52:07 +0200 Subject: [PATCH 2/3] Add function declaration to symbol table --- parser/src/parser/ast.rs | 1 + typechecker/src/build.rs | 3 + typechecker/src/semantic_analyzer.rs | 54 +++++++++---- ...echecker__build__tests__assign_stmt-2.snap | 2 - ...echecker__build__tests__assign_stmt-3.snap | 11 +-- ...echecker__build__tests__assign_stmt-4.snap | 2 - ...echecker__build__tests__assign_stmt-5.snap | 1 - ...echecker__build__tests__assign_stmt-6.snap | 79 +++++++++++++++++++ ...ypechecker__build__tests__assign_stmt.snap | 2 - typechecker/src/symbol_table.rs | 18 ++++- 10 files changed, 141 insertions(+), 32 deletions(-) create mode 100644 typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap diff --git a/parser/src/parser/ast.rs b/parser/src/parser/ast.rs index 5f3e765c..158a2920 100644 --- a/parser/src/parser/ast.rs +++ b/parser/src/parser/ast.rs @@ -40,6 +40,7 @@ pub struct Module { pub body: Vec, } +// Use box to reduce the enum size #[derive(Debug, Clone)] pub enum Statement { AssignStatement(Assign), diff --git a/typechecker/src/build.rs b/typechecker/src/build.rs index d4966da8..223870a0 100644 --- a/typechecker/src/build.rs +++ b/typechecker/src/build.rs @@ -111,6 +111,9 @@ mod tests { "c,d = 1,2", "a: int = 1", "a += b", + "def f(): + a = 1 +", ]; for source in sources { let path = write_temp_source(source); diff --git a/typechecker/src/semantic_analyzer.rs b/typechecker/src/semantic_analyzer.rs index 76d0ba69..15f061d6 100644 --- a/typechecker/src/semantic_analyzer.rs +++ b/typechecker/src/semantic_analyzer.rs @@ -1,10 +1,13 @@ +use std::collections::HashMap; + use parser::ast::Expression; use crate::{ ast_visitor::TraversalVisitor, nodes::EnderpyFile, symbol_table::{ - Declaration, DeclarationPath, Function, SymbolScope, SymbolTable, SymbolTableNode, Variable, + Declaration, DeclarationPath, Function, SymbolScope, SymbolTable, SymbolTableNode, + SymbolTableScope, SymbolTableType, Variable, }, }; @@ -13,6 +16,8 @@ pub struct SemanticAnalyzer { // TODO: Replace errors with another type file: Box, errors: Vec, + + // TOD: Not needed? scope: SymbolScope, } @@ -34,7 +39,6 @@ impl SemanticAnalyzer { module_public: false, module_hidden: false, implicit: false, - scope: self.scope, }; self.globals.add_symbol(symbol_node) } @@ -44,8 +48,12 @@ impl SemanticAnalyzer { .push(String::from(format!("cannot resolve reference {}", ""))) } - fn current_scope(&self) -> SymbolScope { - SymbolScope::Global + fn current_scope(&self) -> &SymbolTableType { + return self.globals.current_scope_type(); + } + + fn is_inside_class(&self) -> bool { + return matches!(self.current_scope(), SymbolTableType::Class); } fn create_variable_declaration_symbol( @@ -59,7 +67,8 @@ impl SemanticAnalyzer { Expression::Name(n) => { let decl = Declaration::Variable(Box::new(Variable { declaration_path, - scope: self.current_scope(), + // TODO: Hacky way + scope: SymbolScope::Global, type_annotation, inferred_type_source: value, is_constant: false, @@ -226,18 +235,35 @@ impl TraversalVisitor for SemanticAnalyzer { module_name: self.file.module_name.clone(), node: f.node, }; - let functionDeclaration = Function { - declaration_path, - scope: self.current_scope(), - is_method: todo!(), - is_generator: todo!(), - return_statements: todo!(), - yeild_statements: todo!(), - raise_statements: todo!(), - }; + self.globals.enter_scope(SymbolTableScope::new( + crate::symbol_table::SymbolTableType::Function, + )); + let mut return_statements = vec![]; + let mut yeild_statements = vec![]; + let mut raise_statements = vec![]; for stmt in &f.body { self.visit_stmt(&stmt); + match &stmt { + parser::ast::Statement::Raise(r) => raise_statements.push(r.clone()), + parser::ast::Statement::Return(r) => return_statements.push(r.clone()), + parser::ast::Statement::ExpressionStatement(e) => match e { + parser::ast::Expression::Yield(y) => yeild_statements.push(*y.clone()), + _ => (), + }, + _ => (), + } } + self.globals.exit_scope(); + + let function_declaration = Declaration::Function(Box::new(Function { + declaration_path, + is_method: self.is_inside_class(), + is_generator: !yeild_statements.is_empty(), + return_statements, + yeild_statements, + raise_statements, + })); + self.create_symbol(f.name.clone(), function_declaration); } fn visit_class_def(&mut self, c: &parser::ast::ClassDef) { diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap index 1d5d9472..2fccd604 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-2.snap @@ -5,7 +5,6 @@ description: b = a + 1 SymbolTable { scopes: [ SymbolTableScope { - start_line_number: 0, symbol_table_type: Module, symbols: { "b": SymbolTableNode { @@ -60,7 +59,6 @@ SymbolTable { module_public: false, module_hidden: false, implicit: false, - scope: Global, }, }, }, diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap index 44b7ea99..3a918a3b 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap @@ -5,11 +5,10 @@ description: "c,d = 1,2" SymbolTable { scopes: [ SymbolTableScope { - start_line_number: 0, symbol_table_type: Module, symbols: { - "d": SymbolTableNode { - name: "d", + "c": SymbolTableNode { + name: "c", declarations: [ Variable( Variable { @@ -63,10 +62,9 @@ SymbolTable { module_public: false, module_hidden: false, implicit: false, - scope: Global, }, - "c": SymbolTableNode { - name: "c", + "d": SymbolTableNode { + name: "d", declarations: [ Variable( Variable { @@ -120,7 +118,6 @@ SymbolTable { module_public: false, module_hidden: false, implicit: false, - scope: Global, }, }, }, diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap index d9a85c02..9fa5d625 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-4.snap @@ -5,7 +5,6 @@ description: "a: int = 1" SymbolTable { scopes: [ SymbolTableScope { - start_line_number: 0, symbol_table_type: Module, symbols: { "a": SymbolTableNode { @@ -52,7 +51,6 @@ SymbolTable { module_public: false, module_hidden: false, implicit: false, - scope: Global, }, }, }, diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap index dec1da2a..45ec782e 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-5.snap @@ -5,7 +5,6 @@ description: a += b SymbolTable { scopes: [ SymbolTableScope { - start_line_number: 0, symbol_table_type: Module, symbols: {}, }, diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap new file mode 100644 index 00000000..8fbdeb4e --- /dev/null +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap @@ -0,0 +1,79 @@ +--- +source: typechecker/src/build.rs +description: "def f():\n a = 1\n" +--- +SymbolTable { + scopes: [ + SymbolTableScope { + symbol_table_type: Module, + symbols: { + "f": SymbolTableNode { + name: "f", + declarations: [ + Function( + Function { + declaration_path: DeclarationPath { + module_name: "test", + node: Node { + start: 0, + end: 18, + }, + }, + is_method: false, + is_generator: false, + return_statements: [], + yeild_statements: [], + raise_statements: [], + }, + ), + ], + module_public: false, + module_hidden: false, + implicit: false, + }, + }, + }, + ], + all_scopes: [ + SymbolTableScope { + symbol_table_type: Function, + symbols: { + "a": SymbolTableNode { + name: "a", + declarations: [ + Variable( + Variable { + declaration_path: DeclarationPath { + module_name: "test", + node: Node { + start: 12, + end: 17, + }, + }, + scope: Global, + type_annotation: None, + inferred_type_source: Some( + Constant( + Constant { + node: Node { + start: 16, + end: 17, + }, + value: Int( + "1", + ), + }, + ), + ), + is_constant: false, + }, + ), + ], + module_public: false, + module_hidden: false, + implicit: false, + }, + }, + }, + ], +} diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap index 06a423fe..4008af7e 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt.snap @@ -5,7 +5,6 @@ description: "a = 'hello world'" SymbolTable { scopes: [ SymbolTableScope { - start_line_number: 0, symbol_table_type: Module, symbols: { "a": SymbolTableNode { @@ -42,7 +41,6 @@ SymbolTable { module_public: false, module_hidden: false, implicit: false, - scope: Global, }, }, }, diff --git a/typechecker/src/symbol_table.rs b/typechecker/src/symbol_table.rs index 17f077ee..af4bd473 100644 --- a/typechecker/src/symbol_table.rs +++ b/typechecker/src/symbol_table.rs @@ -11,11 +11,19 @@ pub struct SymbolTable { #[derive(Debug)] pub struct SymbolTableScope { - pub start_line_number: u8, pub symbol_table_type: SymbolTableType, symbols: HashMap, } +impl SymbolTableScope { + pub fn new(symbol_table_type: SymbolTableType) -> Self { + SymbolTableScope { + symbol_table_type, + symbols: HashMap::new(), + } + } +} + #[derive(Debug)] pub enum SymbolTableType { Module, @@ -30,7 +38,6 @@ pub struct SymbolTableNode { pub module_public: bool, pub module_hidden: bool, pub implicit: bool, - pub scope: SymbolScope, } #[derive(Debug, Clone)] @@ -57,7 +64,6 @@ pub struct Variable { #[derive(Debug)] pub struct Function { pub declaration_path: DeclarationPath, - pub scope: SymbolScope, pub is_method: bool, pub is_generator: bool, pub return_statements: Vec, @@ -77,7 +83,6 @@ pub enum SymbolScope { impl SymbolTable { pub fn new(symbol_table_type: SymbolTableType, start_line_number: u8) -> Self { let global_scope = SymbolTableScope { - start_line_number, symbol_table_type, symbols: HashMap::new(), }; @@ -94,6 +99,11 @@ impl SymbolTable { panic!("no scopes") } } + + pub fn current_scope_type(&self) -> &SymbolTableType { + return &self.current_scope().symbol_table_type; + } + pub fn lookup_in_scope(&self, name: &str) -> Option<&SymbolTableNode> { let cur_scope = self.current_scope(); return cur_scope.symbols.get(name); From e08f6c8d8d30fae490e61d7d350b06cb6dd1d269 Mon Sep 17 00:00:00 2001 From: Glyphack Date: Sun, 6 Aug 2023 18:09:04 +0200 Subject: [PATCH 3/3] Add test for return statements in functions --- typechecker/src/build.rs | 1 + typechecker/src/semantic_analyzer.rs | 4 +--- .../typechecker__build__tests__assign_stmt-3.snap | 8 ++++---- .../typechecker__build__tests__assign_stmt-6.snap | 14 +++++++++++--- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/typechecker/src/build.rs b/typechecker/src/build.rs index 223870a0..7ad5f3d7 100644 --- a/typechecker/src/build.rs +++ b/typechecker/src/build.rs @@ -113,6 +113,7 @@ mod tests { "a += b", "def f(): a = 1 + return ", ]; for source in sources { diff --git a/typechecker/src/semantic_analyzer.rs b/typechecker/src/semantic_analyzer.rs index 15f061d6..448ccd5b 100644 --- a/typechecker/src/semantic_analyzer.rs +++ b/typechecker/src/semantic_analyzer.rs @@ -444,9 +444,7 @@ impl TraversalVisitor for SemanticAnalyzer { todo!() } - fn visit_return(&mut self, r: &parser::ast::Return) { - todo!() - } + fn visit_return(&mut self, r: &parser::ast::Return) {} fn visit_raise(&mut self, r: &parser::ast::Raise) { todo!() diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap index 3a918a3b..1d0e505d 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-3.snap @@ -7,8 +7,8 @@ SymbolTable { SymbolTableScope { symbol_table_type: Module, symbols: { - "c": SymbolTableNode { - name: "c", + "d": SymbolTableNode { + name: "d", declarations: [ Variable( Variable { @@ -63,8 +63,8 @@ SymbolTable { module_hidden: false, implicit: false, }, - "d": SymbolTableNode { - name: "d", + "c": SymbolTableNode { + name: "c", declarations: [ Variable( Variable { diff --git a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap index 8fbdeb4e..6ce0592b 100644 --- a/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap +++ b/typechecker/src/snapshots/typechecker__build__tests__assign_stmt-6.snap @@ -1,6 +1,6 @@ --- source: typechecker/src/build.rs -description: "def f():\n a = 1\n" +description: "def f():\n a = 1\n return\n" --- SymbolTable { scopes: [ @@ -16,12 +16,20 @@ SymbolTable { module_name: "test", node: Node { start: 0, - end: 18, + end: 28, }, }, is_method: false, is_generator: false, - return_statements: [], + return_statements: [ + Return { + node: Node { + start: 18, + end: 27, + }, + value: None, + }, + ], yeild_statements: [], raise_statements: [], },