diff --git a/schala-lang/language/src/ast/mod.rs b/schala-lang/language/src/ast/mod.rs index 0bf76b2..721215f 100644 --- a/schala-lang/language/src/ast/mod.rs +++ b/schala-lang/language/src/ast/mod.rs @@ -53,8 +53,6 @@ pub enum StatementKind { Expression(Expression), Declaration(Declaration), Import(ImportSpecifier), - //TODO maybe modules shoudl be a type of declaration - Module(ModuleSpecifier), Flow(FlowControl), } @@ -133,6 +131,7 @@ pub enum Declaration { Interface { name: Rc, signatures: Vec }, //TODO need to limit the types of statements that can be annotated Annotation { name: Rc, arguments: Vec, inner: Box }, + Module { name: Rc, items: Block }, } #[derive(Debug, PartialEq, Clone)] diff --git a/schala-lang/language/src/ast/visitor.rs b/schala-lang/language/src/ast/visitor.rs index 083cd2a..89d4edd 100644 --- a/schala-lang/language/src/ast/visitor.rs +++ b/schala-lang/language/src/ast/visitor.rs @@ -17,10 +17,6 @@ pub trait ASTVisitor: Sized { fn import(&mut self, _import: &ImportSpecifier) -> Recursion { Recursion::Continue } - fn module(&mut self, _module: &ModuleSpecifier) -> Recursion { - Recursion::Continue - } - fn pattern(&mut self, _pat: &Pattern) -> Recursion { Recursion::Continue } @@ -43,10 +39,6 @@ pub fn walk_block(v: &mut V, block: &Block) { Import(ref import_spec) => { v.import(import_spec); } - Module(ref module_spec) => - if let Recursion::Continue = v.module(module_spec) { - walk_block(v, &module_spec.contents); - }, Flow(ref flow_control) => match flow_control { FlowControl::Return(Some(ref retval)) => { walk_expression(v, retval); @@ -68,6 +60,9 @@ pub fn walk_declaration(v: &mut V, decl: &Declaration, id: &ItemI Binding { name: _, constant: _, type_anno: _, expr } => { walk_expression(v, expr); } + Module { name: _, items } => { + walk_block(v, items); + } _ => (), }; } diff --git a/schala-lang/language/src/ast/visualize.rs b/schala-lang/language/src/ast/visualize.rs index 1268a28..7eac88b 100644 --- a/schala-lang/language/src/ast/visualize.rs +++ b/schala-lang/language/src/ast/visualize.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use super::{ Block, Declaration, Expression, ExpressionKind, FlowControl, ImportSpecifier, InvocationArgument, - ModuleSpecifier, Signature, Statement, StatementKind, AST, + Signature, Statement, StatementKind, AST, }; const LEVEL: usize = 2; @@ -36,7 +36,6 @@ fn render_statement(stmt: &Statement, indent: usize, buf: &mut String) { Expression(ref expr) => render_expression(expr, indent, buf), Declaration(ref decl) => render_declaration(decl, indent, buf), Import(ref spec) => render_import(spec, indent, buf), - Module(ref spec) => render_module(spec, indent, buf), Flow(ref flow_control) => render_flow_control(flow_control, indent, buf), } } @@ -166,6 +165,9 @@ fn render_declaration(decl: &Declaration, indent: usize, buf: &mut String) { render_expression(expr, new_indent, buf); newline(buf); } + Module { name, items: _ } => { + write!(buf, "(Module {} )", name).unwrap(); + } _ => (), /* Impl { type_name: TypeIdentifier, interface_name: Option, block: Vec }, Interface { name: Rc, signatures: Vec }, @@ -190,9 +192,6 @@ fn render_signature(sig: &Signature, _indent: usize, buf: &mut String) { fn render_import(_import: &ImportSpecifier, _indent: usize, buf: &mut String) { buf.push_str("(Import )"); } -fn render_module(_expr: &ModuleSpecifier, _indent: usize, buf: &mut String) { - buf.push_str("(Module )"); -} fn render_flow_control(flow: &FlowControl, _indent: usize, buf: &mut String) { use FlowControl::*; diff --git a/schala-lang/language/src/parsing/mod.rs b/schala-lang/language/src/parsing/mod.rs index 0f716de..f5bee46 100644 --- a/schala-lang/language/src/parsing/mod.rs +++ b/schala-lang/language/src/parsing/mod.rs @@ -15,10 +15,10 @@ //! ```text //! program := (statement delimiter)* EOF //! delimiter := NEWLINE | ";" -//! statement := expression | declaration | import | module | flow +//! statement := expression | declaration | import | flow //! block := "{" (statement delimiter)* "}" //! declaration := annotation? declaration | bare_declaration -//! bare_declaration := type_declaration | func_declaration | binding_declaration | impl_declaration +//! bare_declaration := type_declaration | func_declaration | binding_declaration | impl_declaration | module //! ``` //! ## Declarations //! @@ -394,12 +394,11 @@ impl Parser { //TODO handle error recovery here let tok = self.token_handler.peek(); let kind = match tok.get_kind() { - AtSign | Keyword(Let) | Keyword(Type) | Keyword(Func) | Keyword(Interface) | Keyword(Impl) => - self.declaration().map(StatementKind::Declaration), + AtSign | Keyword(Let) | Keyword(Type) | Keyword(Func) | Keyword(Interface) | Keyword(Impl) + | Keyword(Module) => self.declaration().map(StatementKind::Declaration), Keyword(Continue) | Keyword(Return) | Keyword(Break) => self.flow_control().map(StatementKind::Flow), Keyword(Import) => self.import_declaration().map(StatementKind::Import), - Keyword(Module) => self.module_declaration().map(StatementKind::Module), _ => self.expression().map(StatementKind::Expression), }?; let id = self.id_store.fresh(); @@ -414,6 +413,7 @@ impl Parser { Keyword(Func) => self.func_declaration(), Keyword(Interface) => self.interface_declaration(), Keyword(Impl) => self.impl_declaration(), + Keyword(Module) => self.module_declaration(), _ => return ParseError::new_with_token("Bad parse state encountered", self.token_handler.peek()), } } @@ -1382,11 +1382,11 @@ impl Parser { } #[recursive_descent_method] - fn module_declaration(&mut self) -> ParseResult { + fn module_declaration(&mut self) -> ParseResult { expect!(self, Keyword(Kw::Module)); let name = self.identifier()?; - let contents = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict); - Ok(ModuleSpecifier { name, contents: contents.into() }) + let items = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict); + Ok(Declaration::Module { name, items: items.into() }) } } diff --git a/schala-lang/language/src/parsing/test.rs b/schala-lang/language/src/parsing/test.rs index 4eb8194..fe78bdf 100644 --- a/schala-lang/language/src/parsing/test.rs +++ b/schala-lang/language/src/parsing/test.rs @@ -974,9 +974,9 @@ fn modules() { fn nah() { 33 } } "#, - vec![stmt(StatementKind::Module(ModuleSpecifier { + vec![stmt(StatementKind::Declaration(Declaration::Module { name: rc("ephraim"), - contents: vec![ + items: vec![ decl(Declaration::Binding { name: rc("a"), constant: false, type_anno: None, expr: expr(ExpressionKind::NatLiteral(10)) diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index c8f60cb..b95a7c6 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -76,10 +76,9 @@ impl<'a, 'b> Reducer<'a, 'b> { if let ast::Declaration::FuncDecl(_, statements) = decl { self.insert_function_definition(item_id, statements); }, + // Imports should have already been processed by the symbol table and are irrelevant + // for this representation. ast::StatementKind::Import(..) => (), - ast::StatementKind::Module(_modspec) => { - //TODO handle modules - } ast::StatementKind::Flow(..) => { //TODO this should be an error } @@ -100,13 +99,9 @@ impl<'a, 'b> Reducer<'a, 'b> { let def_id = symbol.def_id().unwrap(); Some(Statement::Binding { id: def_id, constant: *constant, expr: self.expression(expr) }) } - _ => None, }, - ast::StatementKind::Module(_) | ast::StatementKind::Import(_) => { - //TODO need to handle function-internal modules, imports - None - } + ast::StatementKind::Import(_) => None, ast::StatementKind::Flow(ast::FlowControl::Return(expr)) => if let Some(expr) = expr { Some(Statement::Return(self.expression(expr))) diff --git a/schala-lang/language/src/symbol_table/mod.rs b/schala-lang/language/src/symbol_table/mod.rs index ed40eea..32fbfc5 100644 --- a/schala-lang/language/src/symbol_table/mod.rs +++ b/schala-lang/language/src/symbol_table/mod.rs @@ -10,7 +10,7 @@ use std::{ use crate::{ ast, ast::{ - Declaration, Expression, ExpressionKind, ItemId, ModuleSpecifier, Statement, StatementKind, TypeBody, + Declaration, Expression, ExpressionKind, ItemId, Statement, StatementKind, TypeBody, TypeSingletonName, Variant, VariantKind, }, builtin::Builtin, @@ -354,10 +354,10 @@ impl<'a> SymbolTableRunner<'a> { scope_stack.pop(); output } - StatementKind::Module(ModuleSpecifier { name, contents }) => { + StatementKind::Declaration(Declaration::Module { name, items }) => { let new_scope = ScopeSegment::Name(name.clone()); scope_stack.push(new_scope); - let output = self.add_from_scope(contents.as_ref(), scope_stack, false); + let output = self.add_from_scope(items.as_ref(), scope_stack, false); scope_stack.pop(); output } @@ -413,7 +413,7 @@ impl<'a> SymbolTableRunner<'a> { self.add_symbol(id, fq_binding, SymbolSpec::GlobalBinding); } } - StatementKind::Module(ModuleSpecifier { name, .. }) => { + StatementKind::Declaration(Declaration::Module { name, .. }) => { let fq_module = Fqsn::from_scope_stack(scope_stack, name.clone()); self.table.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?; }