Make modules a type of declaration
This commit is contained in:
parent
63ef1451d9
commit
3e16070602
@ -53,8 +53,6 @@ pub enum StatementKind {
|
|||||||
Expression(Expression),
|
Expression(Expression),
|
||||||
Declaration(Declaration),
|
Declaration(Declaration),
|
||||||
Import(ImportSpecifier),
|
Import(ImportSpecifier),
|
||||||
//TODO maybe modules shoudl be a type of declaration
|
|
||||||
Module(ModuleSpecifier),
|
|
||||||
Flow(FlowControl),
|
Flow(FlowControl),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +131,7 @@ pub enum Declaration {
|
|||||||
Interface { name: Rc<String>, signatures: Vec<Signature> },
|
Interface { name: Rc<String>, signatures: Vec<Signature> },
|
||||||
//TODO need to limit the types of statements that can be annotated
|
//TODO need to limit the types of statements that can be annotated
|
||||||
Annotation { name: Rc<String>, arguments: Vec<Expression>, inner: Box<Statement> },
|
Annotation { name: Rc<String>, arguments: Vec<Expression>, inner: Box<Statement> },
|
||||||
|
Module { name: Rc<String>, items: Block },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -17,10 +17,6 @@ pub trait ASTVisitor: Sized {
|
|||||||
fn import(&mut self, _import: &ImportSpecifier) -> Recursion {
|
fn import(&mut self, _import: &ImportSpecifier) -> Recursion {
|
||||||
Recursion::Continue
|
Recursion::Continue
|
||||||
}
|
}
|
||||||
fn module(&mut self, _module: &ModuleSpecifier) -> Recursion {
|
|
||||||
Recursion::Continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pattern(&mut self, _pat: &Pattern) -> Recursion {
|
fn pattern(&mut self, _pat: &Pattern) -> Recursion {
|
||||||
Recursion::Continue
|
Recursion::Continue
|
||||||
}
|
}
|
||||||
@ -43,10 +39,6 @@ pub fn walk_block<V: ASTVisitor>(v: &mut V, block: &Block) {
|
|||||||
Import(ref import_spec) => {
|
Import(ref import_spec) => {
|
||||||
v.import(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 {
|
Flow(ref flow_control) => match flow_control {
|
||||||
FlowControl::Return(Some(ref retval)) => {
|
FlowControl::Return(Some(ref retval)) => {
|
||||||
walk_expression(v, retval);
|
walk_expression(v, retval);
|
||||||
@ -68,6 +60,9 @@ pub fn walk_declaration<V: ASTVisitor>(v: &mut V, decl: &Declaration, id: &ItemI
|
|||||||
Binding { name: _, constant: _, type_anno: _, expr } => {
|
Binding { name: _, constant: _, type_anno: _, expr } => {
|
||||||
walk_expression(v, expr);
|
walk_expression(v, expr);
|
||||||
}
|
}
|
||||||
|
Module { name: _, items } => {
|
||||||
|
walk_block(v, items);
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Block, Declaration, Expression, ExpressionKind, FlowControl, ImportSpecifier, InvocationArgument,
|
Block, Declaration, Expression, ExpressionKind, FlowControl, ImportSpecifier, InvocationArgument,
|
||||||
ModuleSpecifier, Signature, Statement, StatementKind, AST,
|
Signature, Statement, StatementKind, AST,
|
||||||
};
|
};
|
||||||
|
|
||||||
const LEVEL: usize = 2;
|
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),
|
Expression(ref expr) => render_expression(expr, indent, buf),
|
||||||
Declaration(ref decl) => render_declaration(decl, indent, buf),
|
Declaration(ref decl) => render_declaration(decl, indent, buf),
|
||||||
Import(ref spec) => render_import(spec, 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),
|
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);
|
render_expression(expr, new_indent, buf);
|
||||||
newline(buf);
|
newline(buf);
|
||||||
}
|
}
|
||||||
|
Module { name, items: _ } => {
|
||||||
|
write!(buf, "(Module {} <body>)", name).unwrap();
|
||||||
|
}
|
||||||
_ => (), /*
|
_ => (), /*
|
||||||
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
|
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
|
||||||
Interface { name: Rc<String>, signatures: Vec<Signature> },
|
Interface { name: Rc<String>, signatures: Vec<Signature> },
|
||||||
@ -190,9 +192,6 @@ fn render_signature(sig: &Signature, _indent: usize, buf: &mut String) {
|
|||||||
fn render_import(_import: &ImportSpecifier, _indent: usize, buf: &mut String) {
|
fn render_import(_import: &ImportSpecifier, _indent: usize, buf: &mut String) {
|
||||||
buf.push_str("(Import <some import>)");
|
buf.push_str("(Import <some import>)");
|
||||||
}
|
}
|
||||||
fn render_module(_expr: &ModuleSpecifier, _indent: usize, buf: &mut String) {
|
|
||||||
buf.push_str("(Module <some mod>)");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_flow_control(flow: &FlowControl, _indent: usize, buf: &mut String) {
|
fn render_flow_control(flow: &FlowControl, _indent: usize, buf: &mut String) {
|
||||||
use FlowControl::*;
|
use FlowControl::*;
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
//! ```text
|
//! ```text
|
||||||
//! program := (statement delimiter)* EOF
|
//! program := (statement delimiter)* EOF
|
||||||
//! delimiter := NEWLINE | ";"
|
//! delimiter := NEWLINE | ";"
|
||||||
//! statement := expression | declaration | import | module | flow
|
//! statement := expression | declaration | import | flow
|
||||||
//! block := "{" (statement delimiter)* "}"
|
//! block := "{" (statement delimiter)* "}"
|
||||||
//! declaration := annotation? declaration | bare_declaration
|
//! 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
|
//! ## Declarations
|
||||||
//!
|
//!
|
||||||
@ -394,12 +394,11 @@ impl Parser {
|
|||||||
//TODO handle error recovery here
|
//TODO handle error recovery here
|
||||||
let tok = self.token_handler.peek();
|
let tok = self.token_handler.peek();
|
||||||
let kind = match tok.get_kind() {
|
let kind = match tok.get_kind() {
|
||||||
AtSign | Keyword(Let) | Keyword(Type) | Keyword(Func) | Keyword(Interface) | Keyword(Impl) =>
|
AtSign | Keyword(Let) | Keyword(Type) | Keyword(Func) | Keyword(Interface) | Keyword(Impl)
|
||||||
self.declaration().map(StatementKind::Declaration),
|
| Keyword(Module) => self.declaration().map(StatementKind::Declaration),
|
||||||
Keyword(Continue) | Keyword(Return) | Keyword(Break) =>
|
Keyword(Continue) | Keyword(Return) | Keyword(Break) =>
|
||||||
self.flow_control().map(StatementKind::Flow),
|
self.flow_control().map(StatementKind::Flow),
|
||||||
Keyword(Import) => self.import_declaration().map(StatementKind::Import),
|
Keyword(Import) => self.import_declaration().map(StatementKind::Import),
|
||||||
Keyword(Module) => self.module_declaration().map(StatementKind::Module),
|
|
||||||
_ => self.expression().map(StatementKind::Expression),
|
_ => self.expression().map(StatementKind::Expression),
|
||||||
}?;
|
}?;
|
||||||
let id = self.id_store.fresh();
|
let id = self.id_store.fresh();
|
||||||
@ -414,6 +413,7 @@ impl Parser {
|
|||||||
Keyword(Func) => self.func_declaration(),
|
Keyword(Func) => self.func_declaration(),
|
||||||
Keyword(Interface) => self.interface_declaration(),
|
Keyword(Interface) => self.interface_declaration(),
|
||||||
Keyword(Impl) => self.impl_declaration(),
|
Keyword(Impl) => self.impl_declaration(),
|
||||||
|
Keyword(Module) => self.module_declaration(),
|
||||||
_ => return ParseError::new_with_token("Bad parse state encountered", self.token_handler.peek()),
|
_ => return ParseError::new_with_token("Bad parse state encountered", self.token_handler.peek()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1382,11 +1382,11 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn module_declaration(&mut self) -> ParseResult<ModuleSpecifier> {
|
fn module_declaration(&mut self) -> ParseResult<Declaration> {
|
||||||
expect!(self, Keyword(Kw::Module));
|
expect!(self, Keyword(Kw::Module));
|
||||||
let name = self.identifier()?;
|
let name = self.identifier()?;
|
||||||
let contents = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
let items = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
Ok(ModuleSpecifier { name, contents: contents.into() })
|
Ok(Declaration::Module { name, items: items.into() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,9 +974,9 @@ fn modules() {
|
|||||||
fn nah() { 33 }
|
fn nah() { 33 }
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
vec![stmt(StatementKind::Module(ModuleSpecifier {
|
vec![stmt(StatementKind::Declaration(Declaration::Module {
|
||||||
name: rc("ephraim"),
|
name: rc("ephraim"),
|
||||||
contents: vec![
|
items: vec![
|
||||||
decl(Declaration::Binding {
|
decl(Declaration::Binding {
|
||||||
name: rc("a"), constant: false, type_anno: None,
|
name: rc("a"), constant: false, type_anno: None,
|
||||||
expr: expr(ExpressionKind::NatLiteral(10))
|
expr: expr(ExpressionKind::NatLiteral(10))
|
||||||
|
@ -76,10 +76,9 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
|||||||
if let ast::Declaration::FuncDecl(_, statements) = decl {
|
if let ast::Declaration::FuncDecl(_, statements) = decl {
|
||||||
self.insert_function_definition(item_id, statements);
|
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::Import(..) => (),
|
||||||
ast::StatementKind::Module(_modspec) => {
|
|
||||||
//TODO handle modules
|
|
||||||
}
|
|
||||||
ast::StatementKind::Flow(..) => {
|
ast::StatementKind::Flow(..) => {
|
||||||
//TODO this should be an error
|
//TODO this should be an error
|
||||||
}
|
}
|
||||||
@ -100,13 +99,9 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
|||||||
let def_id = symbol.def_id().unwrap();
|
let def_id = symbol.def_id().unwrap();
|
||||||
Some(Statement::Binding { id: def_id, constant: *constant, expr: self.expression(expr) })
|
Some(Statement::Binding { id: def_id, constant: *constant, expr: self.expression(expr) })
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
ast::StatementKind::Module(_) | ast::StatementKind::Import(_) => {
|
ast::StatementKind::Import(_) => None,
|
||||||
//TODO need to handle function-internal modules, imports
|
|
||||||
None
|
|
||||||
}
|
|
||||||
ast::StatementKind::Flow(ast::FlowControl::Return(expr)) =>
|
ast::StatementKind::Flow(ast::FlowControl::Return(expr)) =>
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
Some(Statement::Return(self.expression(expr)))
|
Some(Statement::Return(self.expression(expr)))
|
||||||
|
@ -10,7 +10,7 @@ use std::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
ast,
|
ast,
|
||||||
ast::{
|
ast::{
|
||||||
Declaration, Expression, ExpressionKind, ItemId, ModuleSpecifier, Statement, StatementKind, TypeBody,
|
Declaration, Expression, ExpressionKind, ItemId, Statement, StatementKind, TypeBody,
|
||||||
TypeSingletonName, Variant, VariantKind,
|
TypeSingletonName, Variant, VariantKind,
|
||||||
},
|
},
|
||||||
builtin::Builtin,
|
builtin::Builtin,
|
||||||
@ -354,10 +354,10 @@ impl<'a> SymbolTableRunner<'a> {
|
|||||||
scope_stack.pop();
|
scope_stack.pop();
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
StatementKind::Module(ModuleSpecifier { name, contents }) => {
|
StatementKind::Declaration(Declaration::Module { name, items }) => {
|
||||||
let new_scope = ScopeSegment::Name(name.clone());
|
let new_scope = ScopeSegment::Name(name.clone());
|
||||||
scope_stack.push(new_scope);
|
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();
|
scope_stack.pop();
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
@ -413,7 +413,7 @@ impl<'a> SymbolTableRunner<'a> {
|
|||||||
self.add_symbol(id, fq_binding, SymbolSpec::GlobalBinding);
|
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());
|
let fq_module = Fqsn::from_scope_stack(scope_stack, name.clone());
|
||||||
self.table.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?;
|
self.table.fq_names.register(fq_module, NameSpec { location, kind: NameKind::Module })?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user