Remove all the rest of the instances of Meta from the AST
Still need to do tests
This commit is contained in:
parent
cf9ce74394
commit
71b3365de2
@ -80,7 +80,7 @@ impl From<Expression> for Meta<Expression> {
|
|||||||
pub struct AST {
|
pub struct AST {
|
||||||
#[derivative(PartialEq="ignore")]
|
#[derivative(PartialEq="ignore")]
|
||||||
pub id: ItemId,
|
pub id: ItemId,
|
||||||
pub statements: Vec<Meta<Statement>>
|
pub statements: Vec<Statement>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Derivative, Debug, Clone)]
|
#[derive(Derivative, Debug, Clone)]
|
||||||
@ -93,11 +93,11 @@ pub struct Statement {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum StatementKind {
|
pub enum StatementKind {
|
||||||
Expression(Meta<Expression>),
|
Expression(Expression),
|
||||||
Declaration(Declaration), //TODO Declaration should also be Meta-wrapped; only Expression and Declaration are Meta-wrapped maybe?
|
Declaration(Declaration), //TODO Declaration should also be Meta-wrapped; only Expression and Declaration are Meta-wrapped maybe?
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Block = Vec<Meta<Statement>>;
|
pub type Block = Vec<Statement>;
|
||||||
pub type ParamName = Rc<String>;
|
pub type ParamName = Rc<String>;
|
||||||
|
|
||||||
#[derive(Debug, Derivative, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
@ -111,7 +111,7 @@ pub struct QualifiedName {
|
|||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct FormalParam {
|
pub struct FormalParam {
|
||||||
pub name: ParamName,
|
pub name: ParamName,
|
||||||
pub default: Option<Meta<Expression>>,
|
pub default: Option<Expression>,
|
||||||
pub anno: Option<TypeIdentifier>
|
pub anno: Option<TypeIdentifier>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ pub enum Declaration {
|
|||||||
name: Rc<String>,
|
name: Rc<String>,
|
||||||
constant: bool,
|
constant: bool,
|
||||||
type_anno: Option<TypeIdentifier>,
|
type_anno: Option<TypeIdentifier>,
|
||||||
expr: Meta<Expression>,
|
expr: Expression,
|
||||||
},
|
},
|
||||||
Impl {
|
Impl {
|
||||||
type_name: TypeIdentifier,
|
type_name: TypeIdentifier,
|
||||||
@ -200,28 +200,28 @@ pub enum ExpressionKind {
|
|||||||
FloatLiteral(f64),
|
FloatLiteral(f64),
|
||||||
StringLiteral(Rc<String>),
|
StringLiteral(Rc<String>),
|
||||||
BoolLiteral(bool),
|
BoolLiteral(bool),
|
||||||
BinExp(BinOp, Box<Meta<Expression>>, Box<Meta<Expression>>),
|
BinExp(BinOp, Box<Expression>, Box<Expression>),
|
||||||
PrefixExp(PrefixOp, Box<Meta<Expression>>),
|
PrefixExp(PrefixOp, Box<Expression>),
|
||||||
TupleLiteral(Vec<Meta<Expression>>),
|
TupleLiteral(Vec<Expression>),
|
||||||
Value(QualifiedName),
|
Value(QualifiedName),
|
||||||
NamedStruct {
|
NamedStruct {
|
||||||
name: Meta<QualifiedName>,
|
name: QualifiedName,
|
||||||
fields: Vec<(Rc<String>, Meta<Expression>)>,
|
fields: Vec<(Rc<String>, Expression)>,
|
||||||
},
|
},
|
||||||
Call {
|
Call {
|
||||||
f: Box<Meta<Expression>>,
|
f: Box<Expression>,
|
||||||
arguments: Vec<InvocationArgument>,
|
arguments: Vec<InvocationArgument>,
|
||||||
},
|
},
|
||||||
Index {
|
Index {
|
||||||
indexee: Box<Meta<Expression>>,
|
indexee: Box<Expression>,
|
||||||
indexers: Vec<Meta<Expression>>,
|
indexers: Vec<Expression>,
|
||||||
},
|
},
|
||||||
IfExpression {
|
IfExpression {
|
||||||
discriminator: Box<Discriminator>,
|
discriminator: Box<Discriminator>,
|
||||||
body: Box<IfExpressionBody>,
|
body: Box<IfExpressionBody>,
|
||||||
},
|
},
|
||||||
WhileExpression {
|
WhileExpression {
|
||||||
condition: Option<Box<Meta<Expression>>>,
|
condition: Option<Box<Expression>>,
|
||||||
body: Block,
|
body: Block,
|
||||||
},
|
},
|
||||||
ForExpression {
|
ForExpression {
|
||||||
@ -233,23 +233,23 @@ pub enum ExpressionKind {
|
|||||||
type_anno: Option<TypeIdentifier>,
|
type_anno: Option<TypeIdentifier>,
|
||||||
body: Block,
|
body: Block,
|
||||||
},
|
},
|
||||||
ListLiteral(Vec<Meta<Expression>>),
|
ListLiteral(Vec<Expression>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum InvocationArgument {
|
pub enum InvocationArgument {
|
||||||
Positional(Meta<Expression>),
|
Positional(Expression),
|
||||||
Keyword {
|
Keyword {
|
||||||
name: Rc<String>,
|
name: Rc<String>,
|
||||||
expr: Meta<Expression>,
|
expr: Expression,
|
||||||
},
|
},
|
||||||
Ignored
|
Ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Discriminator {
|
pub enum Discriminator {
|
||||||
Simple(Meta<Expression>),
|
Simple(Expression),
|
||||||
BinOp(Meta<Expression>, BinOp)
|
BinOp(Expression, BinOp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
@ -332,7 +332,7 @@ impl Parser {
|
|||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
_ => statements.push(
|
_ => statements.push(
|
||||||
Meta::new(self.statement()?)
|
self.statement()?
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,9 +459,9 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn nonempty_func_body(&mut self) -> ParseResult<Vec<Meta<Statement>>> {
|
fn nonempty_func_body(&mut self) -> ParseResult<Vec<Statement>> {
|
||||||
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
Ok(statements.into_iter().map(|s| Meta::new(s)).collect())
|
Ok(statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -751,7 +751,7 @@ impl Parser {
|
|||||||
0 => Ok(Expression::new(self.id_store.fresh(), TupleLiteral(vec![]))),
|
0 => Ok(Expression::new(self.id_store.fresh(), TupleLiteral(vec![]))),
|
||||||
1 => Ok(inner.pop().unwrap()),
|
1 => Ok(inner.pop().unwrap()),
|
||||||
_ => {
|
_ => {
|
||||||
let inner: Vec<Meta<Expression>> = inner.into_iter().map(|ex| ex.into()).collect();
|
let inner: Vec<Expression> = inner.into_iter().map(|ex| ex.into()).collect();
|
||||||
Ok(Expression::new(self.id_store.fresh(), TupleLiteral(inner)))
|
Ok(Expression::new(self.id_store.fresh(), TupleLiteral(inner)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -767,7 +767,7 @@ impl Parser {
|
|||||||
Ok(match self.token_handler.peek_kind() {
|
Ok(match self.token_handler.peek_kind() {
|
||||||
LCurlyBrace if !self.restrictions.no_struct_literal => {
|
LCurlyBrace if !self.restrictions.no_struct_literal => {
|
||||||
let fields = self.record_block()?;
|
let fields = self.record_block()?;
|
||||||
Expression::new(self.id_store.fresh(), NamedStruct { name: Meta::new(qualified_identifier), fields })
|
Expression::new(self.id_store.fresh(), NamedStruct { name: qualified_identifier, fields })
|
||||||
},
|
},
|
||||||
_ => Expression::new(self.id_store.fresh(), Value(qualified_identifier))
|
_ => Expression::new(self.id_store.fresh(), Value(qualified_identifier))
|
||||||
})
|
})
|
||||||
@ -789,7 +789,7 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn record_block(&mut self) -> ParseResult<Vec<(Rc<String>, Meta<Expression>)>> {
|
fn record_block(&mut self) -> ParseResult<Vec<(Rc<String>, Expression)>> {
|
||||||
Ok(
|
Ok(
|
||||||
delimited!(self, LCurlyBrace, record_entry, Comma, RCurlyBrace)
|
delimited!(self, LCurlyBrace, record_entry, Comma, RCurlyBrace)
|
||||||
.into_iter().map(|(s, ex)| (s, ex.into())).collect()
|
.into_iter().map(|(s, ex)| (s, ex.into())).collect()
|
||||||
@ -1055,7 +1055,7 @@ impl Parser {
|
|||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn block(&mut self) -> ParseResult<Block> {
|
fn block(&mut self) -> ParseResult<Block> {
|
||||||
let block = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
let block = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
Ok(block.into_iter().map(|s| { Meta::new(s) }).collect())
|
Ok(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -1065,7 +1065,7 @@ impl Parser {
|
|||||||
_ => {
|
_ => {
|
||||||
let expr = self.expression()?;
|
let expr = self.expression()?;
|
||||||
let s = Statement { id: self.id_store.fresh(), kind: StatementKind::Expression(expr.into()) };
|
let s = Statement { id: self.id_store.fresh(), kind: StatementKind::Expression(expr.into()) };
|
||||||
Ok(vec![Meta::new(s)])
|
Ok(vec![s])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1125,7 +1125,7 @@ impl Parser {
|
|||||||
Ok(match tok.get_kind() {
|
Ok(match tok.get_kind() {
|
||||||
LCurlyBrace => {
|
LCurlyBrace => {
|
||||||
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
StatementBlock(statements.into_iter().map(|s| Meta::new(s)).collect())
|
StatementBlock(statements)
|
||||||
},
|
},
|
||||||
Keyword(Kw::Return) => {
|
Keyword(Kw::Return) => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
|
@ -125,8 +125,8 @@ impl<'a> Reducer<'a> {
|
|||||||
ReducedAST(output)
|
ReducedAST(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&mut self, stmt: &Meta<Statement>) -> Stmt {
|
fn statement(&mut self, stmt: &Statement) -> Stmt {
|
||||||
match &stmt.node().kind {
|
match &stmt.kind {
|
||||||
StatementKind::Expression(expr) => Stmt::Expr(self.expression(&expr)),
|
StatementKind::Expression(expr) => Stmt::Expr(self.expression(&expr)),
|
||||||
StatementKind::Declaration(decl) => self.declaration(&decl),
|
StatementKind::Declaration(decl) => self.declaration(&decl),
|
||||||
}
|
}
|
||||||
@ -145,11 +145,10 @@ impl<'a> Reducer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression(&mut self, expr: &Meta<Expression>) -> Expr {
|
fn expression(&mut self, expr: &Expression) -> Expr {
|
||||||
use crate::ast::ExpressionKind::*;
|
use crate::ast::ExpressionKind::*;
|
||||||
let symbol_table = self.symbol_table;
|
let symbol_table = self.symbol_table;
|
||||||
let ref node = expr.node();
|
let ref input = expr.kind;
|
||||||
let ref input = node.kind;
|
|
||||||
match input {
|
match input {
|
||||||
NatLiteral(n) => Expr::Lit(Lit::Nat(*n)),
|
NatLiteral(n) => Expr::Lit(Lit::Nat(*n)),
|
||||||
FloatLiteral(f) => Expr::Lit(Lit::Float(*f)),
|
FloatLiteral(f) => Expr::Lit(Lit::Float(*f)),
|
||||||
@ -180,7 +179,7 @@ impl<'a> Reducer<'a> {
|
|||||||
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| self.expression(e)).collect()),
|
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| self.expression(e)).collect()),
|
||||||
IfExpression { discriminator, body } => self.reduce_if_expression(discriminator, body),
|
IfExpression { discriminator, body } => self.reduce_if_expression(discriminator, body),
|
||||||
Lambda { params, body, .. } => self.reduce_lambda(params, body),
|
Lambda { params, body, .. } => self.reduce_lambda(params, body),
|
||||||
NamedStruct { name, fields } => self.reduce_named_struct(name.node(), fields),
|
NamedStruct { name, fields } => self.reduce_named_struct(name, fields),
|
||||||
Index { .. } => Expr::UnimplementedSigilValue,
|
Index { .. } => Expr::UnimplementedSigilValue,
|
||||||
WhileExpression { .. } => Expr::UnimplementedSigilValue,
|
WhileExpression { .. } => Expr::UnimplementedSigilValue,
|
||||||
ForExpression { .. } => Expr::UnimplementedSigilValue,
|
ForExpression { .. } => Expr::UnimplementedSigilValue,
|
||||||
@ -196,7 +195,7 @@ impl<'a> Reducer<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_named_struct(&mut self, name: &QualifiedName, fields: &Vec<(Rc<String>, Meta<Expression>)>) -> Expr {
|
fn reduce_named_struct(&mut self, name: &QualifiedName, fields: &Vec<(Rc<String>, Expression)>) -> Expr {
|
||||||
let symbol_table = self.symbol_table;
|
let symbol_table = self.symbol_table;
|
||||||
let ref sym_name = match symbol_table.get_fqsn_from_id(&name.id) {
|
let ref sym_name = match symbol_table.get_fqsn_from_id(&name.id) {
|
||||||
Some(fqsn) => fqsn,
|
Some(fqsn) => fqsn,
|
||||||
@ -225,7 +224,7 @@ impl<'a> Reducer<'a> {
|
|||||||
Expr::Call { f, args }
|
Expr::Call { f, args }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_call_expression(&mut self, func: &Meta<Expression>, arguments: &Vec<InvocationArgument>) -> Expr {
|
fn reduce_call_expression(&mut self, func: &Expression, arguments: &Vec<InvocationArgument>) -> Expr {
|
||||||
Expr::Call {
|
Expr::Call {
|
||||||
f: Box::new(self.expression(func)),
|
f: Box::new(self.expression(func)),
|
||||||
args: arguments.iter().map(|arg| self.invocation_argument(arg)).collect(),
|
args: arguments.iter().map(|arg| self.invocation_argument(arg)).collect(),
|
||||||
@ -291,7 +290,7 @@ impl<'a> Reducer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binop(&mut self, binop: &BinOp, lhs: &Box<Meta<Expression>>, rhs: &Box<Meta<Expression>>) -> Expr {
|
fn binop(&mut self, binop: &BinOp, lhs: &Box<Expression>, rhs: &Box<Expression>) -> Expr {
|
||||||
let operation = Builtin::from_str(binop.sigil()).ok();
|
let operation = Builtin::from_str(binop.sigil()).ok();
|
||||||
match operation {
|
match operation {
|
||||||
Some(Builtin::Assignment) => Expr::Assign {
|
Some(Builtin::Assignment) => Expr::Assign {
|
||||||
@ -309,7 +308,7 @@ impl<'a> Reducer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix(&mut self, prefix: &PrefixOp, arg: &Box<Meta<Expression>>) -> Expr {
|
fn prefix(&mut self, prefix: &PrefixOp, arg: &Box<Expression>) -> Expr {
|
||||||
match prefix.builtin {
|
match prefix.builtin {
|
||||||
Some(op) => {
|
Some(op) => {
|
||||||
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
|
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
|
||||||
|
@ -10,16 +10,16 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
ScopeResolver { symbol_table }
|
ScopeResolver { symbol_table }
|
||||||
}
|
}
|
||||||
pub fn resolve(&mut self, ast: &mut AST) -> Result<(), String> {
|
pub fn resolve(&mut self, ast: &mut AST) -> Result<(), String> {
|
||||||
for statement in ast.statements.iter_mut() {
|
for statement in ast.statements.iter() {
|
||||||
match statement.mut_node().kind {
|
match statement.kind {
|
||||||
StatementKind::Declaration(ref mut decl) => self.decl(decl),
|
StatementKind::Declaration(ref decl) => self.decl(decl),
|
||||||
StatementKind::Expression(ref mut expr) => self.expr(expr),
|
StatementKind::Expression(ref expr) => self.expr(expr),
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decl(&mut self, decl: &mut Declaration) -> Result<(), String> {
|
fn decl(&mut self, decl: &Declaration) -> Result<(), String> {
|
||||||
use Declaration::*;
|
use Declaration::*;
|
||||||
match decl {
|
match decl {
|
||||||
Binding { expr, .. } => self.expr(expr),
|
Binding { expr, .. } => self.expr(expr),
|
||||||
@ -27,75 +27,74 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn block(&mut self, block: &mut Block) -> Result<(), String> {
|
fn block(&mut self, block: &Block) -> Result<(), String> {
|
||||||
for statement in block.iter_mut() {
|
for statement in block.iter() {
|
||||||
match statement.mut_node().kind {
|
match statement.kind {
|
||||||
StatementKind::Declaration(ref mut decl) => self.decl(decl),
|
StatementKind::Declaration(ref decl) => self.decl(decl),
|
||||||
StatementKind::Expression(ref mut expr) => self.expr(expr),
|
StatementKind::Expression(ref expr) => self.expr(expr),
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr(&mut self, expr: &mut Meta<Expression>) -> Result<(), String> {
|
fn expr(&mut self, expr: &Expression) -> Result<(), String> {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
let inner_expr = expr.mut_node();
|
match &expr.kind {
|
||||||
match &mut inner_expr.kind {
|
|
||||||
ExpressionKind::Value(qualified_name) => {
|
ExpressionKind::Value(qualified_name) => {
|
||||||
let fqsn = lookup_name_in_scope(&qualified_name);
|
let fqsn = lookup_name_in_scope(&qualified_name);
|
||||||
let ref id = qualified_name.id;
|
let ref id = qualified_name.id;
|
||||||
self.symbol_table.map_id_to_fqsn(id, fqsn);
|
self.symbol_table.map_id_to_fqsn(id, fqsn);
|
||||||
},
|
},
|
||||||
NamedStruct { name, .. } => {
|
NamedStruct { name, .. } => {
|
||||||
let ref id = name.node().id;
|
let ref id = name.id;
|
||||||
let fqsn = lookup_name_in_scope(&name.node());
|
let fqsn = lookup_name_in_scope(&name);
|
||||||
self.symbol_table.map_id_to_fqsn(id, fqsn);
|
self.symbol_table.map_id_to_fqsn(id, fqsn);
|
||||||
},
|
},
|
||||||
BinExp(_, ref mut lhs, ref mut rhs) => {
|
BinExp(_, ref lhs, ref rhs) => {
|
||||||
self.expr(lhs)?;
|
self.expr(lhs)?;
|
||||||
self.expr(rhs)?;
|
self.expr(rhs)?;
|
||||||
},
|
},
|
||||||
PrefixExp(_, ref mut arg) => {
|
PrefixExp(_, ref arg) => {
|
||||||
self.expr(arg)?;
|
self.expr(arg)?;
|
||||||
},
|
},
|
||||||
TupleLiteral(exprs) => {
|
TupleLiteral(exprs) => {
|
||||||
for expr in exprs.iter_mut() {
|
for expr in exprs.iter() {
|
||||||
self.expr(expr)?;
|
self.expr(expr)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Call { ref mut f, arguments } => {
|
Call { f, arguments } => {
|
||||||
self.expr(f)?;
|
self.expr(&f)?;
|
||||||
for arg in arguments.iter_mut() {
|
for arg in arguments.iter() {
|
||||||
self.invoc(arg)?;
|
self.invoc(arg)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Lambda { params, body, .. } => {
|
Lambda { params, body, .. } => {
|
||||||
self.block(body)?;
|
self.block(&body)?;
|
||||||
for param in params.iter_mut() {
|
for param in params.iter() {
|
||||||
if let Some(ref mut expr) = param.default {
|
if let Some(ref expr) = param.default {
|
||||||
self.expr(expr)?;
|
self.expr(expr)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
IfExpression { ref mut body, ref mut discriminator } => {
|
IfExpression { ref body, ref discriminator } => {
|
||||||
match &mut **discriminator {
|
match &**discriminator {
|
||||||
Discriminator::Simple(expr) | Discriminator::BinOp(expr, _) => self.expr(expr)?
|
Discriminator::Simple(expr) | Discriminator::BinOp(expr, _) => self.expr(expr)?
|
||||||
};
|
};
|
||||||
|
|
||||||
match &mut **body {
|
match &**body {
|
||||||
IfExpressionBody::SimplePatternMatch(ref mut pat, ref mut alt1, ref mut alt2) => {
|
IfExpressionBody::SimplePatternMatch(ref pat, ref alt1, ref alt2) => {
|
||||||
self.pattern(pat)?;
|
self.pattern(pat)?;
|
||||||
self.block(alt1)?;
|
self.block(alt1)?;
|
||||||
if let Some(alt) = alt2.as_mut() {
|
if let Some(alt) = alt2 {
|
||||||
self.block(alt)?;
|
self.block(alt)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
IfExpressionBody::GuardList(guardarms) => {
|
IfExpressionBody::GuardList(guardarms) => {
|
||||||
for arm in guardarms.iter_mut() {
|
for arm in guardarms.iter() {
|
||||||
if let Guard::Pat(ref mut pat) = arm.guard {
|
if let Guard::Pat(ref pat) = arm.guard {
|
||||||
self.pattern(pat)?;
|
self.pattern(pat)?;
|
||||||
}
|
}
|
||||||
self.block(&mut arm.body)?;
|
self.block(&arm.body)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
@ -106,7 +105,7 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invoc(&mut self, invoc: &mut InvocationArgument) -> Result<(), String> {
|
fn invoc(&mut self, invoc: &InvocationArgument) -> Result<(), String> {
|
||||||
use InvocationArgument::*;
|
use InvocationArgument::*;
|
||||||
match invoc {
|
match invoc {
|
||||||
Positional(expr) => self.expr(expr),
|
Positional(expr) => self.expr(expr),
|
||||||
@ -115,7 +114,7 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pattern(&mut self, pat: &mut Pattern) -> Result<(), String> {
|
fn pattern(&mut self, pat: &Pattern) -> Result<(), String> {
|
||||||
use Pattern::*;
|
use Pattern::*;
|
||||||
match pat {
|
match pat {
|
||||||
Ignored => (),
|
Ignored => (),
|
||||||
@ -145,7 +144,7 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// this might be a variable or a pattern. if a variable, set to none
|
/// this might be a variable or a pattern. if a variable, set to none
|
||||||
fn qualified_name_in_pattern(&mut self, qualified_name: &mut QualifiedName) {
|
fn qualified_name_in_pattern(&mut self, qualified_name: &QualifiedName) {
|
||||||
let ref id = qualified_name.id;
|
let ref id = qualified_name.id;
|
||||||
let fqsn = lookup_name_in_scope(qualified_name);
|
let fqsn = lookup_name_in_scope(qualified_name);
|
||||||
if self.symbol_table.lookup_by_fqsn(&fqsn).is_some() {
|
if self.symbol_table.lookup_by_fqsn(&fqsn).is_some() {
|
||||||
|
@ -5,7 +5,7 @@ use std::fmt;
|
|||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::ast::{ItemId, Meta, TypeBody, TypeSingletonName, Signature, Statement, StatementKind};
|
use crate::ast::{ItemId, TypeBody, TypeSingletonName, Signature, Statement, StatementKind};
|
||||||
use crate::typechecking::TypeName;
|
use crate::typechecking::TypeName;
|
||||||
|
|
||||||
type LineNumber = u32;
|
type LineNumber = u32;
|
||||||
@ -164,7 +164,7 @@ impl SymbolTable {
|
|||||||
self.add_symbols_from_scope(&ast.statements, &mut scope_name_stack)
|
self.add_symbols_from_scope(&ast.statements, &mut scope_name_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec<Meta<Statement>>, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {
|
fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec<Statement>, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {
|
||||||
use self::ast::Declaration::*;
|
use self::ast::Declaration::*;
|
||||||
|
|
||||||
fn insert_and_check_duplicate_symbol(table: &mut SymbolTrackTable, name: &Rc<String>) -> Result<(), String> {
|
fn insert_and_check_duplicate_symbol(table: &mut SymbolTrackTable, name: &Rc<String>) -> Result<(), String> {
|
||||||
@ -183,8 +183,7 @@ impl SymbolTable {
|
|||||||
|
|
||||||
let mut seen_identifiers: SymbolTrackTable = HashMap::new();
|
let mut seen_identifiers: SymbolTrackTable = HashMap::new();
|
||||||
|
|
||||||
for meta in statements.iter() {
|
for statement in statements.iter() {
|
||||||
let statement = meta.node();
|
|
||||||
if let Statement { kind: StatementKind::Declaration(decl), .. } = statement {
|
if let Statement { kind: StatementKind::Declaration(decl), .. } = statement {
|
||||||
match decl {
|
match decl {
|
||||||
FuncSig(ref signature) => {
|
FuncSig(ref signature) => {
|
||||||
|
@ -265,14 +265,14 @@ impl<'a> TypeContext<'a> {
|
|||||||
pub fn typecheck(&mut self, ast: &AST) -> Result<Type, TypeError> {
|
pub fn typecheck(&mut self, ast: &AST) -> Result<Type, TypeError> {
|
||||||
let mut returned_type = Type::Const(TypeConst::Unit);
|
let mut returned_type = Type::Const(TypeConst::Unit);
|
||||||
for statement in ast.statements.iter() {
|
for statement in ast.statements.iter() {
|
||||||
returned_type = self.statement(statement.node())?;
|
returned_type = self.statement(statement)?;
|
||||||
}
|
}
|
||||||
Ok(returned_type)
|
Ok(returned_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&mut self, statement: &Statement) -> InferResult<Type> {
|
fn statement(&mut self, statement: &Statement) -> InferResult<Type> {
|
||||||
match &statement.kind {
|
match &statement.kind {
|
||||||
StatementKind::Expression(e) => self.expr(e.node()),
|
StatementKind::Expression(e) => self.expr(e),
|
||||||
StatementKind::Declaration(decl) => self.decl(&decl),
|
StatementKind::Declaration(decl) => self.decl(&decl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,7 +281,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
use self::Declaration::*;
|
use self::Declaration::*;
|
||||||
match decl {
|
match decl {
|
||||||
Binding { name, expr, .. } => {
|
Binding { name, expr, .. } => {
|
||||||
let ty = self.expr(expr.node())?;
|
let ty = self.expr(expr)?;
|
||||||
self.variable_map.insert(name.clone(), ty);
|
self.variable_map.insert(name.clone(), ty);
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -292,7 +292,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
fn invoc(&mut self, invoc: &InvocationArgument) -> InferResult<Type> {
|
fn invoc(&mut self, invoc: &InvocationArgument) -> InferResult<Type> {
|
||||||
use InvocationArgument::*;
|
use InvocationArgument::*;
|
||||||
match invoc {
|
match invoc {
|
||||||
Positional(expr) => self.expr(expr.node()),
|
Positional(expr) => self.expr(expr),
|
||||||
_ => Ok(ty!(Nat)) //TODO this is wrong
|
_ => Ok(ty!(Nat)) //TODO this is wrong
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,8 +315,8 @@ impl<'a> TypeContext<'a> {
|
|||||||
BoolLiteral(_) => ty!(Bool),
|
BoolLiteral(_) => ty!(Bool),
|
||||||
FloatLiteral(_) => ty!(Float),
|
FloatLiteral(_) => ty!(Float),
|
||||||
StringLiteral(_) => ty!(StringT),
|
StringLiteral(_) => ty!(StringT),
|
||||||
PrefixExp(op, expr) => self.prefix(op, expr.node())?,
|
PrefixExp(op, expr) => self.prefix(op, expr)?,
|
||||||
BinExp(op, lhs, rhs) => self.binexp(op, lhs.node(), rhs.node())?,
|
BinExp(op, lhs, rhs) => self.binexp(op, lhs, rhs)?,
|
||||||
IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
|
IfExpression { discriminator, body } => self.if_expr(discriminator, body)?,
|
||||||
Value(val) => self.handle_value(val)?,
|
Value(val) => self.handle_value(val)?,
|
||||||
Call { box ref f, arguments } => self.call(f, arguments)?,
|
Call { box ref f, arguments } => self.call(f, arguments)?,
|
||||||
@ -350,7 +350,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
|
fn if_expr(&mut self, discriminator: &Discriminator, body: &IfExpressionBody) -> InferResult<Type> {
|
||||||
use self::Discriminator::*; use self::IfExpressionBody::*;
|
use self::Discriminator::*; use self::IfExpressionBody::*;
|
||||||
match (discriminator, body) {
|
match (discriminator, body) {
|
||||||
(Simple(expr), SimpleConditional(then_clause, else_clause)) => self.handle_simple_if(expr.node(), then_clause, else_clause),
|
(Simple(expr), SimpleConditional(then_clause, else_clause)) => self.handle_simple_if(expr, then_clause, else_clause),
|
||||||
_ => TypeError::new(format!("Complex conditionals not supported"))
|
_ => TypeError::new(format!("Complex conditionals not supported"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,8 +384,8 @@ impl<'a> TypeContext<'a> {
|
|||||||
Ok(ty!(argument_types, ret_type))
|
Ok(ty!(argument_types, ret_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, f: &Meta<Expression>, args: &Vec<InvocationArgument>) -> InferResult<Type> {
|
fn call(&mut self, f: &Expression, args: &Vec<InvocationArgument>) -> InferResult<Type> {
|
||||||
let tf = self.expr(f.node())?;
|
let tf = self.expr(f)?;
|
||||||
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.invoc(ex)).collect();
|
let arg_types: InferResult<Vec<Type>> = args.iter().map(|ex| self.invoc(ex)).collect();
|
||||||
let arg_types = arg_types?;
|
let arg_types = arg_types?;
|
||||||
self.handle_apply(tf, arg_types)
|
self.handle_apply(tf, arg_types)
|
||||||
@ -406,8 +406,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
|
|
||||||
fn block(&mut self, block: &Block) -> InferResult<Type> {
|
fn block(&mut self, block: &Block) -> InferResult<Type> {
|
||||||
let mut output = ty!(Unit);
|
let mut output = ty!(Unit);
|
||||||
for s in block.iter() {
|
for statement in block.iter() {
|
||||||
let statement = s.node();
|
|
||||||
output = self.statement(statement)?;
|
output = self.statement(statement)?;
|
||||||
}
|
}
|
||||||
Ok(output)
|
Ok(output)
|
||||||
|
Loading…
Reference in New Issue
Block a user