Enough of ASTVisitor to test something
This commit is contained in:
parent
7533c69c49
commit
d80a0036b1
@ -2,7 +2,9 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use crate::derivative::Derivative;
|
use crate::derivative::Derivative;
|
||||||
|
|
||||||
|
mod walker;
|
||||||
mod visitor;
|
mod visitor;
|
||||||
|
mod visitor_test;
|
||||||
mod operators;
|
mod operators;
|
||||||
pub use operators::*;
|
pub use operators::*;
|
||||||
|
|
||||||
|
@ -1,33 +1,68 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
|
use crate::ast::walker;
|
||||||
|
|
||||||
|
//TODO maybe these functions should take closures that return a KeepRecursing | StopHere type,
|
||||||
|
//or a tuple of (T, <that type>)
|
||||||
|
|
||||||
pub trait ASTVisitor {
|
//TODO default implmentations should call walk methods - then I can test printing
|
||||||
fn visit(&mut self, ast: &mut AST) {
|
pub trait ASTVisitor: Sized {
|
||||||
self.block(&ast.statements);
|
fn visit(&mut self, ast: &AST) {
|
||||||
|
println!("FUCK");
|
||||||
|
walker::ast(self, ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block(&mut self, statements: &Vec<Statement>) {
|
fn block(&mut self, statements: &Vec<Statement>) {
|
||||||
for statement in statements {
|
println!("oi");
|
||||||
self.statement(statement);
|
walker::block(self, statements);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&mut self, statement: &Statement) {
|
fn statement(&mut self, statement: &Statement) {
|
||||||
use StatementKind::*;
|
println!("stmt");
|
||||||
match statement.kind {
|
walker::statement(self, statement);
|
||||||
Expression(ref expr) => self.expression(expr),
|
|
||||||
Declaration(ref decl) => self.declaration(decl),
|
|
||||||
Import(ref import_spec) => self.import(import_spec),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expression(&mut self, expression: &Expression) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declaration(&mut self, declaration: &Declaration) {
|
fn declaration(&mut self, declaration: &Declaration) {
|
||||||
|
walker::declaration(self, declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&mut self, signature: &Signature) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn binding(&mut self, name: &Rc<String>, constant: bool, type_anno: Option<&TypeIdentifier>, expr: &Expression) {
|
||||||
|
walker::maybe_type_identifier(self, type_anno);
|
||||||
|
walker::expression(self, expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expression(&mut self, expression: &Expression) {
|
||||||
|
println!("expr yo");
|
||||||
|
walker::expression(self, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expression_kind(&mut self, kind: &ExpressionKind) {
|
||||||
|
walker::expression_kind(self, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_type_identifier(&mut self, type_anno: Option<&TypeIdentifier>) {
|
||||||
|
walker::maybe_type_identifier(self, type_anno);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import(&mut self, import: &ImportSpecifier) {
|
fn import(&mut self, import: &ImportSpecifier) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn nat_literal(&mut self, n: u64) {}
|
||||||
|
fn float_literal(&mut self, f: f64) {}
|
||||||
|
fn string_literal(&mut self, s: &Rc<String>) {}
|
||||||
|
fn bool_literal(&mut self, b: bool) {}
|
||||||
|
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) {
|
||||||
|
walker::expression(self, lhs);
|
||||||
|
walker::expression(self, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prefix_exp(&mut self, op: &PrefixOp, arg: &Expression) {
|
||||||
|
walker::expression(self, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
36
schala-lang/language/src/ast/visitor_test.rs
Normal file
36
schala-lang/language/src/ast/visitor_test.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
|
||||||
|
use crate::ast::visitor::ASTVisitor;
|
||||||
|
use crate::ast::walker;
|
||||||
|
use crate::util::quick_ast;
|
||||||
|
|
||||||
|
struct Tester {
|
||||||
|
count: u64,
|
||||||
|
float_count: u64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ASTVisitor for Tester {
|
||||||
|
fn nat_literal(&mut self, _n: u64) {
|
||||||
|
self.count += 1;
|
||||||
|
}
|
||||||
|
fn float_literal(&mut self, _f: f64) {
|
||||||
|
self.float_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn foo() {
|
||||||
|
let mut tester = Tester { count: 0, float_count: 0 };
|
||||||
|
let ast = quick_ast(r#"
|
||||||
|
import gragh
|
||||||
|
|
||||||
|
let a = 20 + 84
|
||||||
|
let b = 28 + 1 + 2 + 2.0
|
||||||
|
"#);
|
||||||
|
|
||||||
|
tester.visit(&ast);
|
||||||
|
|
||||||
|
assert_eq!(tester.count, 5);
|
||||||
|
assert_eq!(tester.float_count, 1);
|
||||||
|
}
|
112
schala-lang/language/src/ast/walker.rs
Normal file
112
schala-lang/language/src/ast/walker.rs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
use crate::ast::*;
|
||||||
|
use crate::ast::visitor::ASTVisitor;
|
||||||
|
|
||||||
|
pub fn ast<V: ASTVisitor>(v: &mut V, ast: &AST) {
|
||||||
|
v.block(&ast.statements);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn block<V: ASTVisitor>(v: &mut V, block: &Vec<Statement>) {
|
||||||
|
for statement in block {
|
||||||
|
v.statement(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn statement<V: ASTVisitor>(v: &mut V, statement: &Statement) {
|
||||||
|
use StatementKind::*;
|
||||||
|
match statement.kind {
|
||||||
|
Expression(ref expr) => v.expression(expr),
|
||||||
|
Declaration(ref decl) => v.declaration(decl),
|
||||||
|
Import(ref import_spec) => v.import(import_spec),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declaration<V: ASTVisitor>(v: &mut V, decl: &Declaration) {
|
||||||
|
use Declaration::*;
|
||||||
|
match decl {
|
||||||
|
FuncSig(sig) => {
|
||||||
|
v.signature(&sig);
|
||||||
|
},
|
||||||
|
FuncDecl(sig, block) => {
|
||||||
|
v.signature(&sig);
|
||||||
|
v.block(&block);
|
||||||
|
},
|
||||||
|
TypeDecl { .. } => unimplemented!(),
|
||||||
|
TypeAlias(_, _) => unimplemented!(),
|
||||||
|
Binding { name, constant, type_anno, expr } => {
|
||||||
|
v.binding(name, *constant, type_anno.as_ref(), expr);
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Impl {
|
||||||
|
type_name: TypeIdentifier,
|
||||||
|
interface_name: Option<TypeSingletonName>,
|
||||||
|
block: Vec<Declaration>,
|
||||||
|
},
|
||||||
|
Interface {
|
||||||
|
name: Rc<String>,
|
||||||
|
signatures: Vec<Signature>
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expression<V: ASTVisitor>(v: &mut V, expression: &Expression) {
|
||||||
|
v.expression_kind(&expression.kind);
|
||||||
|
v.maybe_type_identifier(expression.type_anno.as_ref());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_type_identifier<V: ASTVisitor>(v: &mut V, maybe_ty_identifier: Option<&TypeIdentifier>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expression_kind<V: ASTVisitor>(v: &mut V, expression_kind: &ExpressionKind) {
|
||||||
|
use ExpressionKind::*;
|
||||||
|
match expression_kind {
|
||||||
|
NatLiteral(n) => v.nat_literal(*n),
|
||||||
|
FloatLiteral(f) => v.float_literal(*f),
|
||||||
|
StringLiteral(s) => v.string_literal(s),
|
||||||
|
BoolLiteral(b) => v.bool_literal(*b),
|
||||||
|
BinExp(op, lhs, rhs) => v.binexp(op, lhs, rhs),
|
||||||
|
PrefixExp(op, arg) => v.prefix_exp(op, arg),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
TupleLiteral(Vec<Expression>),
|
||||||
|
Value(QualifiedName),
|
||||||
|
NamedStruct {
|
||||||
|
name: QualifiedName,
|
||||||
|
fields: Vec<(Rc<String>, Expression)>,
|
||||||
|
},
|
||||||
|
Call {
|
||||||
|
f: Box<Expression>,
|
||||||
|
arguments: Vec<InvocationArgument>,
|
||||||
|
},
|
||||||
|
Index {
|
||||||
|
indexee: Box<Expression>,
|
||||||
|
indexers: Vec<Expression>,
|
||||||
|
},
|
||||||
|
IfExpression {
|
||||||
|
discriminator: Box<Discriminator>,
|
||||||
|
body: Box<IfExpressionBody>,
|
||||||
|
},
|
||||||
|
WhileExpression {
|
||||||
|
condition: Option<Box<Expression>>,
|
||||||
|
body: Block,
|
||||||
|
},
|
||||||
|
ForExpression {
|
||||||
|
enumerators: Vec<Enumerator>,
|
||||||
|
body: Box<ForBody>,
|
||||||
|
},
|
||||||
|
Lambda {
|
||||||
|
params: Vec<FormalParam>,
|
||||||
|
type_anno: Option<TypeIdentifier>,
|
||||||
|
body: Block,
|
||||||
|
},
|
||||||
|
ListLiteral(Vec<Expression>),
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user