Compare commits
8 Commits
antiquated
...
visitor_ag
Author | SHA1 | Date | |
---|---|---|---|
|
9752e73d2e | ||
|
975951e582 | ||
|
59f5032a61 | ||
|
b0dd1a6527 | ||
|
3dad077a09 | ||
|
74a574b093 | ||
|
a187d43fc1 | ||
|
d043036c61 |
@ -19,6 +19,10 @@ impl<T> Meta<T> {
|
|||||||
pub fn node(&self) -> &T {
|
pub fn node(&self) -> &T {
|
||||||
&self.n
|
&self.n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn node_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.n
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO this PartialEq is here to make tests work - find a way to make it not necessary
|
//TODO this PartialEq is here to make tests work - find a way to make it not necessary
|
||||||
|
@ -34,6 +34,7 @@ mod symbol_table;
|
|||||||
mod builtin;
|
mod builtin;
|
||||||
mod reduced_ast;
|
mod reduced_ast;
|
||||||
mod eval;
|
mod eval;
|
||||||
|
mod visitor;
|
||||||
|
|
||||||
mod schala;
|
mod schala;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable};
|
use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable};
|
||||||
use crate::builtin::{BinOp, PrefixOp};
|
use crate::builtin::{BinOp, PrefixOp};
|
||||||
|
use crate::visitor::{ASTVisitor, Visitable};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ReducedAST(pub Vec<Stmt>);
|
pub struct ReducedAST(pub Vec<Stmt>);
|
||||||
@ -94,6 +95,31 @@ pub enum Func {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Reducer<'a> {
|
||||||
|
symbol_table: &'a SymbolTable,
|
||||||
|
reduced_ast: ReducedAST,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Reducer<'a> {
|
||||||
|
fn new(symbol_table: &'a SymbolTable) -> Reducer {
|
||||||
|
Reducer { symbol_table, reduced_ast: ReducedAST(vec![]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn done(self) -> Result<ReducedAST, String> {
|
||||||
|
Ok(self.reduced_ast)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ASTVisitor for Reducer<'a> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn perform_reduction(mut input: AST, symbol_table: &SymbolTable) -> Result<ReducedAST, String> {
|
||||||
|
let mut reducer = Reducer::new(symbol_table);
|
||||||
|
let _ = input.visit(&mut reducer).map_err(|e| e.to_string())?;
|
||||||
|
reducer.done()
|
||||||
|
}
|
||||||
|
|
||||||
impl AST {
|
impl AST {
|
||||||
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
|
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
@ -159,9 +159,10 @@ fn typechecking(input: ast::AST, handle: &mut Schala, comp: Option<&mut PassDebu
|
|||||||
|
|
||||||
fn ast_reducing(input: ast::AST, handle: &mut Schala, comp: Option<&mut PassDebugArtifact>) -> Result<reduced_ast::ReducedAST, String> {
|
fn ast_reducing(input: ast::AST, handle: &mut Schala, comp: Option<&mut PassDebugArtifact>) -> Result<reduced_ast::ReducedAST, String> {
|
||||||
let ref symbol_table = handle.symbol_table.borrow();
|
let ref symbol_table = handle.symbol_table.borrow();
|
||||||
let output = input.reduce(symbol_table);
|
//let output = input.reduce(symbol_table);
|
||||||
|
let output = reduced_ast::perform_reduction(input, symbol_table);
|
||||||
comp.map(|comp| comp.add_artifact(format!("{:?}", output)));
|
comp.map(|comp| comp.add_artifact(format!("{:?}", output)));
|
||||||
Ok(output)
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval(input: reduced_ast::ReducedAST, handle: &mut Schala, comp: Option<&mut PassDebugArtifact>) -> Result<String, String> {
|
fn eval(input: reduced_ast::ReducedAST, handle: &mut Schala, comp: Option<&mut PassDebugArtifact>) -> Result<String, String> {
|
||||||
|
205
schala-lang/language/src/visitor.rs
Normal file
205
schala-lang/language/src/visitor.rs
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
use crate::ast::*;
|
||||||
|
use crate::builtin::{PrefixOp, BinOp};
|
||||||
|
|
||||||
|
pub type VResult = Result<(), Box<dyn Error>>;
|
||||||
|
|
||||||
|
pub trait ASTVisitor {
|
||||||
|
fn post_ast(&mut self, _: &mut AST) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn post_statement(&mut self, _: &mut Statement) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn post_expression(&mut self, _: &mut Expression) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Visitable {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T: Visitable> Visitable for &mut T {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
self.visit(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visitable> Visitable for Option<T> {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
match self {
|
||||||
|
Some(t) => t.visit(v),
|
||||||
|
None => Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visitable> Visitable for Vec<T> {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
for item in self {
|
||||||
|
item.visit(v)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T: Visitable> Visitable for Box<T> {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
self.visit(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T: Visitable> Visitable for Meta<T> {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
self.node_mut().visit(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for AST {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
for s in self.0.iter_mut() {
|
||||||
|
s.visit(v)?
|
||||||
|
}
|
||||||
|
v.post_ast(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Statement {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
match self {
|
||||||
|
Statement::ExpressionStatement(meta) => meta.visit(v),
|
||||||
|
Statement::Declaration(decl) => decl.visit(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Declaration {
|
||||||
|
fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
use Declaration::*;
|
||||||
|
Ok(match self {
|
||||||
|
FuncSig(sig) => (),
|
||||||
|
FuncDecl(sig, block) => (),
|
||||||
|
TypeDecl { .. } => (),
|
||||||
|
TypeAlias(_, _) => (),
|
||||||
|
Binding { .. } => (),
|
||||||
|
Impl { .. } => (),
|
||||||
|
Interface { .. } => (),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Expression {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
let _ = self.kind.visit(v)?;
|
||||||
|
let _ = self.type_anno.visit(v)?;
|
||||||
|
v.post_expression(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for ExpressionKind {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
use ExpressionKind::*;
|
||||||
|
Ok(match self {
|
||||||
|
NatLiteral(_) | FloatLiteral(_) | StringLiteral(_)
|
||||||
|
| BoolLiteral(_) => (),
|
||||||
|
BinExp(op, lhs, rhs) => {
|
||||||
|
let _ = op.visit(v)?;
|
||||||
|
let _ = lhs.visit(v)?;
|
||||||
|
let _ = rhs.visit(v)?;
|
||||||
|
()
|
||||||
|
},
|
||||||
|
PrefixExp(op, expr) => {
|
||||||
|
let _ = op.visit(v)?;
|
||||||
|
let _ = expr.visit(v)?;
|
||||||
|
()
|
||||||
|
},
|
||||||
|
TupleLiteral(exprs) => exprs.visit(v)?,
|
||||||
|
Value(_) => (),
|
||||||
|
NamedStruct { fields, .. } => {
|
||||||
|
let mut x: Vec<_> = fields.iter_mut().map(|(_, expr)| expr).collect();
|
||||||
|
x.visit(v)?
|
||||||
|
},
|
||||||
|
Call { f, arguments } => {
|
||||||
|
let _ = f.visit(v)?;
|
||||||
|
arguments.visit(v)?
|
||||||
|
},
|
||||||
|
Index { indexee, indexers } => {
|
||||||
|
let _ = indexee.visit(v)?;
|
||||||
|
indexers.visit(v)?
|
||||||
|
},
|
||||||
|
IfExpression { discriminator, body } => {
|
||||||
|
let _ = discriminator.visit(v)?;
|
||||||
|
body.visit(v)?
|
||||||
|
},
|
||||||
|
WhileExpression { condition, body } => {
|
||||||
|
let _ = condition.visit(v)?;
|
||||||
|
body.visit(v)?
|
||||||
|
},
|
||||||
|
ForExpression { enumerators, body } => {
|
||||||
|
let _ = enumerators.visit(v)?;
|
||||||
|
body.visit(v)?
|
||||||
|
},
|
||||||
|
ListLiteral(expressions) => expressions.visit(v)?,
|
||||||
|
Lambda { params, type_anno, body } => {
|
||||||
|
let _ = params.visit(v)?;
|
||||||
|
let _ = type_anno.visit(v)?;
|
||||||
|
body.visit(v)?
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for IfExpressionBody {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Discriminator {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for InvocationArgument {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for BinOp {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for PrefixOp {
|
||||||
|
fn visit(&mut self, v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for TypeIdentifier {
|
||||||
|
fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for Enumerator {
|
||||||
|
fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for ForBody {
|
||||||
|
fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitable for FormalParam {
|
||||||
|
fn visit(&mut self, _v: &mut dyn ASTVisitor) -> VResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user