Compare commits

...

7 Commits

Author SHA1 Message Date
greg
9d24d48825 Add a few more things to an Expression-only visitor 2019-07-30 00:32:25 -07:00
greg
c3c515284d Super-simple visitor doing something 2019-07-29 20:15:34 -07:00
greg
0903277b69 simple expression 2019-07-29 19:44:46 -07:00
greg
94c4dec9a9 Notes 2019-07-28 20:11:19 -07:00
greg
42bc4f091c Rename visitor, add note 2019-07-28 20:11:19 -07:00
greg
be2dcb5301 Add initial visitor.rs 2019-07-28 20:11:19 -07:00
greg
88029fc55a Move bx macro to util 2019-07-28 20:11:19 -07:00
6 changed files with 67 additions and 12 deletions

View File

@ -62,6 +62,7 @@ of learning how to write a programming language.
### General ### General
http://thume.ca/2019/04/18/writing-a-compiler-in-rust/ http://thume.ca/2019/04/18/writing-a-compiler-in-rust/
http://thume.ca/2019/07/14/a-tour-of-metaprogramming-models-for-generics/
### Type-checking ### Type-checking
https://skillsmatter.com/skillscasts/10868-inside-the-rust-compiler https://skillsmatter.com/skillscasts/10868-inside-the-rust-compiler

3
VISITOR_NOTES Normal file
View File

@ -0,0 +1,3 @@
-each terminal node in the AST requires a method on ASTVisitor
-this can maybe be done with a macro?

View File

@ -4,7 +4,7 @@
#![feature(slice_patterns, box_patterns, box_syntax)] #![feature(slice_patterns, box_patterns, box_syntax)]
//! `schala-lang` is where the Schala programming language is actually implemented. //! `schala-lang` is where the Schala programming language is actually implemented.
//! It defines the `Schala` type, which contains the state for a Schala REPL, and implements //! The crate defines the `Schala` type, which contains the state for a Schala REPL, and implements
//! `ProgrammingLanguageInterface` and the chain of compiler passes for it. //! `ProgrammingLanguageInterface` and the chain of compiler passes for it.
extern crate itertools; extern crate itertools;
@ -17,16 +17,10 @@ extern crate schala_repl;
extern crate schala_lang_codegen; extern crate schala_lang_codegen;
extern crate ena; extern crate ena;
macro_rules! bx {
($e:expr) => { Box::new($e) }
}
#[macro_use] #[macro_use]
mod util; mod util;
#[macro_use] #[macro_use]
mod typechecking; mod typechecking;
mod tokenizing; mod tokenizing;
mod ast; mod ast;
mod parsing; mod parsing;
@ -34,7 +28,7 @@ mod symbol_table;
mod builtin; mod builtin;
mod reduced_ast; mod reduced_ast;
mod eval; mod eval;
mod schala; mod schala;
mod visitor;
pub use schala::Schala; pub use schala::Schala;

View File

@ -143,15 +143,11 @@
//! //!
mod test; mod test;
use std::rc::Rc; use std::rc::Rc;
use crate::tokenizing::*; use crate::tokenizing::*;
use crate::tokenizing::Kw::*; use crate::tokenizing::Kw::*;
use crate::tokenizing::TokenKind::*; use crate::tokenizing::TokenKind::*;
use crate::ast::*; use crate::ast::*;
use crate::builtin::{BinOp, PrefixOp}; use crate::builtin::{BinOp, PrefixOp};
/// Represents a parsing error /// Represents a parsing error

View File

@ -2,6 +2,10 @@ use std::collections::HashMap;
use std::hash::Hash; use std::hash::Hash;
use std::cmp::Eq; use std::cmp::Eq;
macro_rules! bx {
($e:expr) => { Box::new($e) }
}
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct ScopeStack<'a, T: 'a, V: 'a> where T: Hash + Eq { pub struct ScopeStack<'a, T: 'a, V: 'a> where T: Hash + Eq {
parent: Option<&'a ScopeStack<'a, T, V>>, parent: Option<&'a ScopeStack<'a, T, V>>,

View File

@ -0,0 +1,57 @@
use std::rc::Rc;
use crate::builtin::{BinOp, PrefixOp};
use crate::ast::{Expression, ExpressionKind, InvocationArgument, Meta};
pub trait ExpressionKindVisitor<T> {
fn nat_literal(&mut self, n: &u64) -> T;
fn float_literal(&mut self, f: &f64) -> T;
fn string_literal(&mut self, s: Rc<String>) -> T;
fn bool_literal(&mut self, b: &bool) -> T;
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> T;
fn prefix_exp(&mut self, op: &PrefixOp, arg: &Expression) -> T;
fn value(&mut self, value_name: Rc<String>) -> T;
fn call_expression(&mut self, f: &Expression, arguments: &Vec<Meta<InvocationArgument>>) -> T;
}
pub fn dispatch<T>(input: &ExpressionKind, visitor: &mut dyn ExpressionKindVisitor<T>) -> T {
use ExpressionKind::*;
match input {
NatLiteral(n) => visitor.nat_literal(n),
FloatLiteral(f) => visitor.float_literal(f),
StringLiteral(s) => visitor.string_literal(s.clone()),
BoolLiteral(b) => visitor.bool_literal(b),
BinExp(op, box lhs, box rhs) => visitor.binexp(op, lhs.node(), rhs.node()),
PrefixExp(op, box arg) => visitor.prefix_exp(op, arg.node()),
Value(val_name) => visitor.value(val_name.clone()),
Call { box f, arguments } => visitor.call_expression(f.node(), arguments),
_ => panic!()
}
}
/*
struct NumberSummer;
impl ExpressionKindVisitor<u64> for NumberSummer {
fn nat_literal(&mut self, n: &u64) -> u64 { n.clone() }
fn float_literal(&mut self, f: &f64) -> u64
fn string_literal(&mut self, s: Rc<String>) -> u64 { 0 }
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> u64 {
let lhs = dispatch(&lhs.kind, self);
let rhs = dispatch(&rhs.kind, self);
lhs + rhs
}
}
#[test]
fn yolo_swagg() {
use super::*;
let mut t = NumberSummer;
let x = ExpressionKind::NatLiteral(4);
let result = dispatch(&x, &mut t);
assert_eq!(result, 4);
}
*/