Grand renaming of things
This commit is contained in:
parent
801896bcc6
commit
dd22ca0291
57
README.md
57
README.md
@ -1,7 +1,11 @@
|
|||||||
Schala
|
|
||||||
======
|
|
||||||
|
|
||||||
## The experimental programming language meta-interpreter
|
TODO:
|
||||||
|
-null-only language should be called Maaru
|
||||||
|
-haskell-ish langauge should be called Robo
|
||||||
|
-typeful scripting language should be called schala
|
||||||
|
rename accordingly!
|
||||||
|
|
||||||
|
# Schala - a programming language meta-interpreter
|
||||||
|
|
||||||
Schala is a Rust-language framework written to make it easy to
|
Schala is a Rust-language framework written to make it easy to
|
||||||
create and experiment with toy programming languages. It provides
|
create and experiment with toy programming languages. It provides
|
||||||
@ -10,34 +14,47 @@ for tokenizing text, parsing tokens, evaluating an abstract syntax tree,
|
|||||||
and other tasks that are common to all programming languages.
|
and other tasks that are common to all programming languages.
|
||||||
|
|
||||||
Schala started out life as an experiment in writing a Javascript-like
|
Schala started out life as an experiment in writing a Javascript-like
|
||||||
programming language that would never encounter any kind of runtime
|
programming language that would never encounter any kind of runtime value
|
||||||
value error, but rather always return `null` under any kind of error
|
error, but rather always return `null` under any kind of error condition. I had
|
||||||
condition. I had seen one too many Javascript `Uncaught TypeError:
|
seen one too many Javascript `Uncaught TypeError: Cannot read property ___ of
|
||||||
Cannot read property ___ of undefined` messages, and I was a bit frustrated.
|
undefined` messages, and I was a bit frustrated. Plus I had always wanted to
|
||||||
Plus I had always wanted to write a programming langauge from scratch,
|
write a programming langauge from scratch, and Rust is a fun language to
|
||||||
and Rust is a fun language to program in.
|
program in. Over time I became interested in playing around with other sorts
|
||||||
|
of programming languages as well, and wanted to make the process as general as
|
||||||
|
possible.
|
||||||
|
|
||||||
Over time I became interested in playing around with other sorts
|
The name of the project comes from Schala the Princess of Zeal from the 1995
|
||||||
of programming languages as well, and wanted to make the process
|
SNES RPG *Chrono Trigger*. I like classic JRPGs and enjoyed the thought of
|
||||||
as general as possible. I changed the name of the project to
|
creating a language name confusingly close to Scala. The naming scheme for
|
||||||
Schala, after the Princess of Zeal from *Chrono Trigger*, because I
|
languages implemented with the Schala meta-interpreter is Chrono Trigger
|
||||||
like classic JRPGs and because it sounds sort of like Scala.
|
characters.
|
||||||
|
|
||||||
Schala is as yet an incomplete personal project that I continue to work
|
## Languages implemented using the meta-interpreter
|
||||||
on as my time permits.
|
|
||||||
|
|
||||||
### Reference works
|
* The eponymous *Schala* language is an interpreted/compiled scripting langauge,
|
||||||
|
designed to be relatively simple, but with a reasonably sophisticated type
|
||||||
|
system.
|
||||||
|
|
||||||
|
* *Maaru* was the original Schala (since renamed to free up the name *Schala*
|
||||||
|
for the above language), a very simple dynamically-typed scripting language
|
||||||
|
such that all possible runtime errors result in null rather than program
|
||||||
|
failure.
|
||||||
|
|
||||||
|
* *Robo* is an experiment in creating a lazy, functional, strongly-typed language
|
||||||
|
much like Haskell
|
||||||
|
|
||||||
|
## Reference works
|
||||||
|
|
||||||
Here's a partial list of resources I've made use of in the process
|
Here's a partial list of resources I've made use of in the process
|
||||||
of learning how to write a programming language.
|
of learning how to write a programming language.
|
||||||
|
|
||||||
#### Evaluation
|
### Evaluation
|
||||||
*Understanding Computation*, Tom Stuart, O'Reilly 2013
|
*Understanding Computation*, Tom Stuart, O'Reilly 2013
|
||||||
|
|
||||||
#### Parsing
|
### Parsing
|
||||||
http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||||
|
|
||||||
[Crafting Interpreters](http://www.craftinginterpreters.com/)
|
[Crafting Interpreters](http://www.craftinginterpreters.com/)
|
||||||
|
|
||||||
#### LLVM
|
### LLVM
|
||||||
http://blog.ulysse.io/2016/07/03/llvm-getting-started.html
|
http://blog.ulysse.io/2016/07/03/llvm-getting-started.html
|
||||||
|
@ -5,7 +5,7 @@ use std::collections::HashMap;
|
|||||||
use self::llvm_sys::prelude::*;
|
use self::llvm_sys::prelude::*;
|
||||||
use self::llvm_sys::{LLVMIntPredicate, LLVMRealPredicate};
|
use self::llvm_sys::{LLVMIntPredicate, LLVMRealPredicate};
|
||||||
|
|
||||||
use schala_lang::parser::{AST, Statement, Function, Prototype, Expression, BinOp};
|
use maaru_lang::parser::{AST, Statement, Function, Prototype, Expression, BinOp};
|
||||||
use language::LLVMCodeString;
|
use language::LLVMCodeString;
|
||||||
|
|
||||||
use llvm_wrap as LLVMWrap;
|
use llvm_wrap as LLVMWrap;
|
@ -2,13 +2,13 @@ extern crate take_mut;
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use schala_lang::parser::{AST, Statement, Expression, Function, Callable, BinOp};
|
use maaru_lang::parser::{AST, Statement, Expression, Function, Callable, BinOp};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::io::{Write, Stdout, BufWriter};
|
use std::io::{Write, Stdout, BufWriter};
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
use schala_lang::parser::Expression::*;
|
use maaru_lang::parser::Expression::*;
|
||||||
use schala_lang::parser::Statement::*;
|
use maaru_lang::parser::Statement::*;
|
||||||
|
|
||||||
type Reduction<T> = (T, Option<SideEffect>);
|
type Reduction<T> = (T, Option<SideEffect>);
|
||||||
|
|
@ -1,157 +1,44 @@
|
|||||||
extern crate itertools;
|
use ::std::marker::PhantomData;
|
||||||
use self::itertools::Itertools;
|
pub mod tokenizer;
|
||||||
|
pub mod parser;
|
||||||
|
pub mod eval;
|
||||||
|
pub mod compilation;
|
||||||
|
|
||||||
use language::{ProgrammingLanguage, EvaluationMachine, ParseError, TokenError, LLVMCodeString};
|
use language::{ProgrammingLanguage, EvaluationMachine, ParseError, TokenError, LLVMCodeString};
|
||||||
|
|
||||||
pub struct Maaru {
|
pub use self::eval::Evaluator as MaaruEvaluator;
|
||||||
}
|
|
||||||
|
|
||||||
impl Maaru {
|
pub struct Maaru<'a> { marker: PhantomData<&'a ()> }
|
||||||
pub fn new() -> Maaru {
|
impl<'a> Maaru<'a> {
|
||||||
Maaru { }
|
pub fn new() -> Maaru <'a> {
|
||||||
|
Maaru { marker: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MaaruEvaluator {
|
impl<'a> ProgrammingLanguage for Maaru<'a> {
|
||||||
pub trace_evaluation: bool,
|
type Token = tokenizer::Token;
|
||||||
}
|
type AST = parser::AST;
|
||||||
|
type Evaluator = MaaruEvaluator<'a>;
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Token {
|
|
||||||
StrLiteral(String),
|
|
||||||
Backtick,
|
|
||||||
Newline,
|
|
||||||
LParen,
|
|
||||||
RParen,
|
|
||||||
LBracket,
|
|
||||||
RBracket,
|
|
||||||
LBrace,
|
|
||||||
RBrace,
|
|
||||||
Period,
|
|
||||||
Comma,
|
|
||||||
Colon,
|
|
||||||
Semicolon,
|
|
||||||
SingleQuote,
|
|
||||||
Identifier(String),
|
|
||||||
Operator(String),
|
|
||||||
NumLiteral(Number),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Number {
|
|
||||||
IntegerRep(String),
|
|
||||||
FloatRep(String)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type AST = Vec<ASTNode>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ASTNode {
|
|
||||||
FunctionDefinition(String, Expression),
|
|
||||||
ImportStatement(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Expression {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProgrammingLanguage for Maaru {
|
|
||||||
type Token = Token;
|
|
||||||
type AST = AST;
|
|
||||||
type Evaluator = MaaruEvaluator;
|
|
||||||
|
|
||||||
fn name() -> String {
|
fn name() -> String {
|
||||||
"Maaru".to_string()
|
"Maaru".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError> {
|
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError> {
|
||||||
use self::Token::*;
|
tokenizer::tokenize(input)
|
||||||
let mut tokens = Vec::new();
|
|
||||||
let mut iter = input.chars().peekable();
|
|
||||||
while let Some(c) = iter.next() {
|
|
||||||
if c == ';' {
|
|
||||||
while let Some(c) = iter.next() {
|
|
||||||
if c == '\n' {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
fn parse(input: Vec<Self::Token>) -> Result<Self::AST, ParseError> {
|
||||||
|
parser::parse(&input, &[]).map_err(|x| ParseError { msg: x.msg })
|
||||||
}
|
}
|
||||||
continue;
|
fn evaluate(ast: Self::AST, evaluator: &mut Self::Evaluator) -> Vec<String> {
|
||||||
|
evaluator.run(ast)
|
||||||
}
|
}
|
||||||
let cur_tok = match c {
|
fn compile(ast: Self::AST) -> LLVMCodeString {
|
||||||
c if char::is_whitespace(c) && c != '\n' => continue,
|
compilation::compile_ast(ast)
|
||||||
'\n' => Newline,
|
|
||||||
'(' => LParen,
|
|
||||||
')' => RParen,
|
|
||||||
'[' => LBracket,
|
|
||||||
']' => RBracket,
|
|
||||||
'{' => LBrace,
|
|
||||||
'}' => RBrace,
|
|
||||||
',' => Comma,
|
|
||||||
':' => Colon,
|
|
||||||
';' => Semicolon,
|
|
||||||
'.' => Period,
|
|
||||||
'`' => Backtick,
|
|
||||||
'\'' => SingleQuote,
|
|
||||||
'"' => {
|
|
||||||
let mut buffer = String::new();
|
|
||||||
loop {
|
|
||||||
match iter.next() {
|
|
||||||
Some(x) if x == '"' => break,
|
|
||||||
Some(x) => buffer.push(x),
|
|
||||||
None => return Err(TokenError::new("Unclosed quote")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StrLiteral(buffer)
|
|
||||||
}
|
|
||||||
c if c.is_digit(10) => {
|
|
||||||
let mut integer = true;
|
|
||||||
let mut buffer = String::new();
|
|
||||||
buffer.push(c);
|
|
||||||
buffer.extend(iter.peeking_take_while(|x| x.is_digit(10)));
|
|
||||||
if let Some(&'.') = iter.peek() {
|
|
||||||
buffer.push(iter.next().unwrap());
|
|
||||||
integer = false;
|
|
||||||
}
|
|
||||||
buffer.extend(iter.peeking_take_while(|x| x.is_digit(10)));
|
|
||||||
let inner = if integer {
|
|
||||||
Number::IntegerRep(buffer)
|
|
||||||
} else {
|
|
||||||
Number::FloatRep(buffer)
|
|
||||||
};
|
|
||||||
NumLiteral(inner)
|
|
||||||
},
|
|
||||||
c if char::is_alphanumeric(c) => {
|
|
||||||
let mut buffer = String::new();
|
|
||||||
buffer.push(c);
|
|
||||||
buffer.extend(iter.peeking_take_while(|x| char::is_alphanumeric(*x)));
|
|
||||||
Identifier(buffer)
|
|
||||||
},
|
|
||||||
c => {
|
|
||||||
let mut buffer = String::new();
|
|
||||||
buffer.push(c);
|
|
||||||
buffer.extend(iter.peeking_take_while(|x| !char::is_whitespace(*x)));
|
|
||||||
Operator(buffer)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
tokens.push(cur_tok);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(tokens)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse(_input: Vec<Self::Token>) -> Result<Self::AST, ParseError> {
|
|
||||||
Ok(vec!())
|
|
||||||
}
|
|
||||||
fn evaluate(_ast: Self::AST, _evaluator: &mut Self::Evaluator) -> Vec<String> {
|
|
||||||
vec!["Unimplemented".to_string()]
|
|
||||||
}
|
|
||||||
fn compile(_ast: Self::AST) -> LLVMCodeString {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EvaluationMachine for MaaruEvaluator {
|
impl<'a> EvaluationMachine for MaaruEvaluator<'a> {
|
||||||
fn set_option(&mut self, option: &str, value: bool) -> bool {
|
fn set_option(&mut self, option: &str, value: bool) -> bool {
|
||||||
if option == "trace_evaluation" {
|
if option == "trace_evaluation" {
|
||||||
self.trace_evaluation = value;
|
self.trace_evaluation = value;
|
||||||
@ -161,9 +48,7 @@ impl EvaluationMachine for MaaruEvaluator {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new() -> MaaruEvaluator {
|
fn new() -> MaaruEvaluator<'a> {
|
||||||
MaaruEvaluator {
|
MaaruEvaluator::new(None)
|
||||||
trace_evaluation: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use schala_lang::tokenizer::{Token, Kw, OpTok};
|
use maaru_lang::tokenizer::{Token, Kw, OpTok};
|
||||||
use schala_lang::tokenizer::Token::*;
|
use maaru_lang::tokenizer::Token::*;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
11
src/main.rs
11
src/main.rs
@ -9,11 +9,14 @@ use std::process;
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
|
||||||
|
/*
|
||||||
mod schala_lang;
|
mod schala_lang;
|
||||||
use schala_lang::SchalaEvaluator;
|
use schala_lang::SchalaEvaluator;
|
||||||
use schala_lang::Schala;
|
use schala_lang::Schala;
|
||||||
|
*/
|
||||||
|
|
||||||
mod maaru_lang;
|
mod maaru_lang;
|
||||||
|
mod robo_lang;
|
||||||
|
|
||||||
mod language;
|
mod language;
|
||||||
use language::{ProgrammingLanguage, LanguageInterface, LLVMCodeString, EvaluationMachine};
|
use language::{ProgrammingLanguage, LanguageInterface, LLVMCodeString, EvaluationMachine};
|
||||||
@ -26,8 +29,8 @@ use virtual_machine::{run_vm, run_assembler};
|
|||||||
fn main() {
|
fn main() {
|
||||||
let languages: Vec<Box<LanguageInterface>> =
|
let languages: Vec<Box<LanguageInterface>> =
|
||||||
vec![
|
vec![
|
||||||
Box::new((Schala::new(), SchalaEvaluator::new(None))),
|
Box::new((maaru_lang::Maaru::new(), maaru_lang::MaaruEvaluator::new(None))),
|
||||||
Box::new((maaru_lang::Maaru::new(), maaru_lang::MaaruEvaluator::new())),
|
Box::new((robo_lang::Robo::new(), robo_lang::RoboEvaluator::new())),
|
||||||
];
|
];
|
||||||
|
|
||||||
let option_matches =
|
let option_matches =
|
||||||
@ -79,7 +82,7 @@ fn main() {
|
|||||||
repl.run();
|
repl.run();
|
||||||
}
|
}
|
||||||
[_, ref filename, _..] => {
|
[_, ref filename, _..] => {
|
||||||
let language = Schala::new();
|
let language = maaru_lang::Maaru::new();
|
||||||
run_noninteractive(filename, &language, trace_evaluation, compile);
|
run_noninteractive(filename, &language, trace_evaluation, compile);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -308,7 +311,7 @@ pub fn compilation_sequence(llvm_code: LLVMCodeString, sourcefile: &str) {
|
|||||||
let obj_filename = "out.o";
|
let obj_filename = "out.o";
|
||||||
let q: Vec<&str> = sourcefile.split('.').collect();
|
let q: Vec<&str> = sourcefile.split('.').collect();
|
||||||
let bin_filename = match &q[..] {
|
let bin_filename = match &q[..] {
|
||||||
&[name, "schala"] => name,
|
&[name, "maaru"] => name,
|
||||||
_ => panic!("Bad filename {}", sourcefile),
|
_ => panic!("Bad filename {}", sourcefile),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
169
src/robo_lang/mod.rs
Normal file
169
src/robo_lang/mod.rs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
extern crate itertools;
|
||||||
|
use self::itertools::Itertools;
|
||||||
|
|
||||||
|
use language::{ProgrammingLanguage, EvaluationMachine, ParseError, TokenError, LLVMCodeString};
|
||||||
|
|
||||||
|
pub struct Robo {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Robo {
|
||||||
|
pub fn new() -> Robo {
|
||||||
|
Robo { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RoboEvaluator {
|
||||||
|
pub trace_evaluation: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Token {
|
||||||
|
StrLiteral(String),
|
||||||
|
Backtick,
|
||||||
|
Newline,
|
||||||
|
LParen,
|
||||||
|
RParen,
|
||||||
|
LBracket,
|
||||||
|
RBracket,
|
||||||
|
LBrace,
|
||||||
|
RBrace,
|
||||||
|
Period,
|
||||||
|
Comma,
|
||||||
|
Colon,
|
||||||
|
Semicolon,
|
||||||
|
SingleQuote,
|
||||||
|
Identifier(String),
|
||||||
|
Operator(String),
|
||||||
|
NumLiteral(Number),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Number {
|
||||||
|
IntegerRep(String),
|
||||||
|
FloatRep(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type AST = Vec<ASTNode>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ASTNode {
|
||||||
|
FunctionDefinition(String, Expression),
|
||||||
|
ImportStatement(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Expression {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgrammingLanguage for Robo {
|
||||||
|
type Token = Token;
|
||||||
|
type AST = AST;
|
||||||
|
type Evaluator = RoboEvaluator;
|
||||||
|
|
||||||
|
fn name() -> String {
|
||||||
|
"Robo".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError> {
|
||||||
|
use self::Token::*;
|
||||||
|
let mut tokens = Vec::new();
|
||||||
|
let mut iter = input.chars().peekable();
|
||||||
|
while let Some(c) = iter.next() {
|
||||||
|
if c == ';' {
|
||||||
|
while let Some(c) = iter.next() {
|
||||||
|
if c == '\n' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let cur_tok = match c {
|
||||||
|
c if char::is_whitespace(c) && c != '\n' => continue,
|
||||||
|
'\n' => Newline,
|
||||||
|
'(' => LParen,
|
||||||
|
')' => RParen,
|
||||||
|
'[' => LBracket,
|
||||||
|
']' => RBracket,
|
||||||
|
'{' => LBrace,
|
||||||
|
'}' => RBrace,
|
||||||
|
',' => Comma,
|
||||||
|
':' => Colon,
|
||||||
|
';' => Semicolon,
|
||||||
|
'.' => Period,
|
||||||
|
'`' => Backtick,
|
||||||
|
'\'' => SingleQuote,
|
||||||
|
'"' => {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
loop {
|
||||||
|
match iter.next() {
|
||||||
|
Some(x) if x == '"' => break,
|
||||||
|
Some(x) => buffer.push(x),
|
||||||
|
None => return Err(TokenError::new("Unclosed quote")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StrLiteral(buffer)
|
||||||
|
}
|
||||||
|
c if c.is_digit(10) => {
|
||||||
|
let mut integer = true;
|
||||||
|
let mut buffer = String::new();
|
||||||
|
buffer.push(c);
|
||||||
|
buffer.extend(iter.peeking_take_while(|x| x.is_digit(10)));
|
||||||
|
if let Some(&'.') = iter.peek() {
|
||||||
|
buffer.push(iter.next().unwrap());
|
||||||
|
integer = false;
|
||||||
|
}
|
||||||
|
buffer.extend(iter.peeking_take_while(|x| x.is_digit(10)));
|
||||||
|
let inner = if integer {
|
||||||
|
Number::IntegerRep(buffer)
|
||||||
|
} else {
|
||||||
|
Number::FloatRep(buffer)
|
||||||
|
};
|
||||||
|
NumLiteral(inner)
|
||||||
|
},
|
||||||
|
c if char::is_alphanumeric(c) => {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
buffer.push(c);
|
||||||
|
buffer.extend(iter.peeking_take_while(|x| char::is_alphanumeric(*x)));
|
||||||
|
Identifier(buffer)
|
||||||
|
},
|
||||||
|
c => {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
buffer.push(c);
|
||||||
|
buffer.extend(iter.peeking_take_while(|x| !char::is_whitespace(*x)));
|
||||||
|
Operator(buffer)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tokens.push(cur_tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(_input: Vec<Self::Token>) -> Result<Self::AST, ParseError> {
|
||||||
|
Ok(vec!())
|
||||||
|
}
|
||||||
|
fn evaluate(_ast: Self::AST, _evaluator: &mut Self::Evaluator) -> Vec<String> {
|
||||||
|
vec!["Unimplemented".to_string()]
|
||||||
|
}
|
||||||
|
fn compile(_ast: Self::AST) -> LLVMCodeString {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EvaluationMachine for RoboEvaluator {
|
||||||
|
fn set_option(&mut self, option: &str, value: bool) -> bool {
|
||||||
|
if option == "trace_evaluation" {
|
||||||
|
self.trace_evaluation = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> RoboEvaluator {
|
||||||
|
RoboEvaluator {
|
||||||
|
trace_evaluation: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,54 +0,0 @@
|
|||||||
use ::std::marker::PhantomData;
|
|
||||||
pub mod tokenizer;
|
|
||||||
pub mod parser;
|
|
||||||
pub mod eval;
|
|
||||||
pub mod compilation;
|
|
||||||
|
|
||||||
use language::{ProgrammingLanguage, EvaluationMachine, ParseError, TokenError, LLVMCodeString};
|
|
||||||
|
|
||||||
pub use self::eval::Evaluator as SchalaEvaluator;
|
|
||||||
|
|
||||||
pub struct Schala<'a> { marker: PhantomData<&'a ()> }
|
|
||||||
impl<'a> Schala<'a> {
|
|
||||||
pub fn new() -> Schala<'a> {
|
|
||||||
Schala { marker: PhantomData }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ProgrammingLanguage for Schala<'a> {
|
|
||||||
type Token = tokenizer::Token;
|
|
||||||
type AST = parser::AST;
|
|
||||||
type Evaluator = SchalaEvaluator<'a>;
|
|
||||||
|
|
||||||
fn name() -> String {
|
|
||||||
"Schala".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tokenize(input: &str) -> Result<Vec<Self::Token>, TokenError> {
|
|
||||||
tokenizer::tokenize(input)
|
|
||||||
}
|
|
||||||
fn parse(input: Vec<Self::Token>) -> Result<Self::AST, ParseError> {
|
|
||||||
parser::parse(&input, &[]).map_err(|x| ParseError { msg: x.msg })
|
|
||||||
}
|
|
||||||
fn evaluate(ast: Self::AST, evaluator: &mut Self::Evaluator) -> Vec<String> {
|
|
||||||
evaluator.run(ast)
|
|
||||||
}
|
|
||||||
fn compile(ast: Self::AST) -> LLVMCodeString {
|
|
||||||
compilation::compile_ast(ast)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> EvaluationMachine for SchalaEvaluator<'a> {
|
|
||||||
fn set_option(&mut self, option: &str, value: bool) -> bool {
|
|
||||||
if option == "trace_evaluation" {
|
|
||||||
self.trace_evaluation = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new() -> SchalaEvaluator<'a> {
|
|
||||||
SchalaEvaluator::new(None)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user