Change name: ASTNode -> Statement
This commit is contained in:
parent
2996198eff
commit
905431b33c
@ -3,7 +3,7 @@ extern crate llvm_sys;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use self::llvm_sys::prelude::*;
|
use self::llvm_sys::prelude::*;
|
||||||
use parser::{AST, ASTNode, Function, Expression};
|
use parser::{AST, Statement, Function, Expression};
|
||||||
|
|
||||||
use llvm_wrap as LLVMWrap;
|
use llvm_wrap as LLVMWrap;
|
||||||
|
|
||||||
@ -95,9 +95,9 @@ impl CodeGen for AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeGen for ASTNode {
|
impl CodeGen for Statement {
|
||||||
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
fn codegen(&self, data: &mut CompilationData) -> LLVMValueRef {
|
||||||
use self::ASTNode::*;
|
use self::Statement::*;
|
||||||
match self {
|
match self {
|
||||||
&ExprNode(ref expr) => expr.codegen(data),
|
&ExprNode(ref expr) => expr.codegen(data),
|
||||||
&FuncDefNode(ref func) => func.codegen(data),
|
&FuncDefNode(ref func) => func.codegen(data),
|
||||||
|
16
src/eval.rs
16
src/eval.rs
@ -1,7 +1,7 @@
|
|||||||
extern crate take_mut;
|
extern crate take_mut;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use parser::{AST, ASTNode, Expression, Function};
|
use parser::{AST, Statement, Expression, Function};
|
||||||
|
|
||||||
type Reduction<T> = (T, Option<SideEffect>);
|
type Reduction<T> = (T, Option<SideEffect>);
|
||||||
|
|
||||||
@ -66,9 +66,9 @@ trait Evaluable {
|
|||||||
fn is_reducible(&self) -> bool;
|
fn is_reducible(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evaluable for ASTNode {
|
impl Evaluable for Statement {
|
||||||
fn is_reducible(&self) -> bool {
|
fn is_reducible(&self) -> bool {
|
||||||
use parser::ASTNode::*;
|
use parser::Statement::*;
|
||||||
match self {
|
match self {
|
||||||
&ExprNode(ref expr) => expr.is_reducible(),
|
&ExprNode(ref expr) => expr.is_reducible(),
|
||||||
&FuncDefNode(_) => true,
|
&FuncDefNode(_) => true,
|
||||||
@ -102,7 +102,7 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Evaluator<'a> {
|
impl<'a> Evaluator<'a> {
|
||||||
fn reduction_loop(&mut self, mut node: ASTNode) -> ASTNode {
|
fn reduction_loop(&mut self, mut node: Statement) -> Statement {
|
||||||
loop {
|
loop {
|
||||||
node = self.step(node);
|
node = self.step(node);
|
||||||
if !node.is_reducible() {
|
if !node.is_reducible() {
|
||||||
@ -112,7 +112,7 @@ impl<'a> Evaluator<'a> {
|
|||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&mut self, node: ASTNode) -> ASTNode {
|
fn step(&mut self, node: Statement) -> Statement {
|
||||||
let (new_node, side_effect) = self.reduce_astnode(node);
|
let (new_node, side_effect) = self.reduce_astnode(node);
|
||||||
if let Some(s) = side_effect {
|
if let Some(s) = side_effect {
|
||||||
self.perform_side_effect(s);
|
self.perform_side_effect(s);
|
||||||
@ -133,8 +133,8 @@ impl<'a> Evaluator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_astnode(&mut self, node: ASTNode) -> Reduction<ASTNode> {
|
fn reduce_astnode(&mut self, node: Statement) -> Reduction<Statement> {
|
||||||
use parser::ASTNode::*;
|
use parser::Statement::*;
|
||||||
match node {
|
match node {
|
||||||
ExprNode(expr) => {
|
ExprNode(expr) => {
|
||||||
if expr.is_reducible() {
|
if expr.is_reducible() {
|
||||||
@ -265,7 +265,7 @@ impl<'a> Evaluator<'a> {
|
|||||||
|
|
||||||
fn reduce_call(&mut self, name: String, arguments: Vec<Expression>) -> Reduction<Expression> {
|
fn reduce_call(&mut self, name: String, arguments: Vec<Expression>) -> Reduction<Expression> {
|
||||||
use parser::Expression::*;
|
use parser::Expression::*;
|
||||||
use parser::ASTNode::*;
|
use parser::Statement::*;
|
||||||
|
|
||||||
// ugly hack for now
|
// ugly hack for now
|
||||||
if name == "print" {
|
if name == "print" {
|
||||||
|
@ -21,7 +21,7 @@ use std::collections::VecDeque;
|
|||||||
//
|
//
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ASTNode {
|
pub enum Statement {
|
||||||
ExprNode(Expression),
|
ExprNode(Expression),
|
||||||
FuncDefNode(Function),
|
FuncDefNode(Function),
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ pub enum ASTNode {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub prototype: Prototype,
|
pub prototype: Prototype,
|
||||||
pub body: Vec<ASTNode>,
|
pub body: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -51,9 +51,9 @@ pub enum Expression {
|
|||||||
Block(VecDeque<Expression>),
|
Block(VecDeque<Expression>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ASTNode {
|
impl fmt::Display for Statement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::ASTNode::*;
|
use self::Statement::*;
|
||||||
match *self {
|
match *self {
|
||||||
ExprNode(ref expr) => write!(f, "{}", expr),
|
ExprNode(ref expr) => write!(f, "{}", expr),
|
||||||
FuncDefNode(_) => write!(f, "UNIMPLEMENTED"),
|
FuncDefNode(_) => write!(f, "UNIMPLEMENTED"),
|
||||||
@ -76,7 +76,7 @@ impl fmt::Display for Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type AST = Vec<ASTNode>;
|
pub type AST = Vec<Statement>;
|
||||||
|
|
||||||
type Precedence = u8;
|
type Precedence = u8;
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ impl Parser {
|
|||||||
fn program(&mut self) -> ParseResult<AST> {
|
fn program(&mut self) -> ParseResult<AST> {
|
||||||
let mut ast = Vec::new(); //TODO have this come from previously-parsed tree
|
let mut ast = Vec::new(); //TODO have this come from previously-parsed tree
|
||||||
loop {
|
loop {
|
||||||
let result: ParseResult<ASTNode> = match self.peek() {
|
let result: ParseResult<Statement> = match self.peek() {
|
||||||
Some(ref t) if is_delimiter(&t) => {
|
Some(ref t) if is_delimiter(&t) => {
|
||||||
self.next();
|
self.next();
|
||||||
continue;
|
continue;
|
||||||
@ -190,24 +190,24 @@ impl Parser {
|
|||||||
Ok(ast)
|
Ok(ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(&mut self) -> ParseResult<ASTNode> {
|
fn statement(&mut self) -> ParseResult<Statement> {
|
||||||
use tokenizer::Token::*;
|
use tokenizer::Token::*;
|
||||||
let node: ASTNode = match self.peek() {
|
let node: Statement = match self.peek() {
|
||||||
Some(Keyword(Kw::Fn)) => try!(self.declaration()),
|
Some(Keyword(Kw::Fn)) => try!(self.declaration()),
|
||||||
Some(_) => ASTNode::ExprNode(try!(self.expression())),
|
Some(_) => Statement::ExprNode(try!(self.expression())),
|
||||||
None => panic!("unexpected end of tokens"),
|
None => panic!("unexpected end of tokens"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declaration(&mut self) -> ParseResult<ASTNode> {
|
fn declaration(&mut self) -> ParseResult<Statement> {
|
||||||
use tokenizer::Token::*;
|
use tokenizer::Token::*;
|
||||||
expect!(self, Keyword(Kw::Fn));
|
expect!(self, Keyword(Kw::Fn));
|
||||||
let prototype = try!(self.prototype());
|
let prototype = try!(self.prototype());
|
||||||
let body: Vec<ASTNode> = try!(self.body());
|
let body: Vec<Statement> = try!(self.body());
|
||||||
expect!(self, Keyword(Kw::End));
|
expect!(self, Keyword(Kw::End));
|
||||||
Ok(ASTNode::FuncDefNode(Function {
|
Ok(Statement::FuncDefNode(Function {
|
||||||
prototype: prototype,
|
prototype: prototype,
|
||||||
body: body,
|
body: body,
|
||||||
}))
|
}))
|
||||||
@ -258,7 +258,7 @@ impl Parser {
|
|||||||
Ok(args)
|
Ok(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn body(&mut self) -> ParseResult<Vec<ASTNode>> {
|
fn body(&mut self) -> ParseResult<Vec<Statement>> {
|
||||||
use tokenizer::Token::*;
|
use tokenizer::Token::*;
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
@ -428,7 +428,7 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(tokens: &[Token], _parsed_tree: &[ASTNode]) -> ParseResult<AST> {
|
pub fn parse(tokens: &[Token], _parsed_tree: &[Statement]) -> ParseResult<AST> {
|
||||||
let mut parser = Parser::initialize(tokens);
|
let mut parser = Parser::initialize(tokens);
|
||||||
parser.program()
|
parser.program()
|
||||||
}
|
}
|
||||||
@ -437,6 +437,8 @@ pub fn parse(tokens: &[Token], _parsed_tree: &[ASTNode]) -> ParseResult<AST> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use tokenizer;
|
use tokenizer;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use super::Statement::*;
|
||||||
|
use super::Expression::*;
|
||||||
|
|
||||||
macro_rules! parsetest {
|
macro_rules! parsetest {
|
||||||
($input:expr, $output:pat, $ifexpr:expr) => {
|
($input:expr, $output:pat, $ifexpr:expr) => {
|
||||||
@ -453,10 +455,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn call_parse_test() {
|
fn call_parse_test() {
|
||||||
use super::ASTNode::*;
|
|
||||||
use super::Expression::*;
|
|
||||||
use super::Function;
|
use super::Function;
|
||||||
|
|
||||||
parsetest!(
|
parsetest!(
|
||||||
"fn a() 1 + 2 end",
|
"fn a() 1 + 2 end",
|
||||||
&[FuncDefNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})],
|
&[FuncDefNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})],
|
||||||
@ -474,8 +473,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expression_parse_test() {
|
fn expression_parse_test() {
|
||||||
use super::ASTNode::*;
|
|
||||||
use super::Expression::*;
|
|
||||||
parsetest!("a", &[ExprNode(Variable(ref s))], s == "a");
|
parsetest!("a", &[ExprNode(Variable(ref s))], s == "a");
|
||||||
parsetest!("a + b",
|
parsetest!("a + b",
|
||||||
&[ExprNode(BinExp(ref plus, box Variable(ref a), box Variable(ref b)))],
|
&[ExprNode(BinExp(ref plus, box Variable(ref a), box Variable(ref b)))],
|
||||||
@ -494,9 +491,6 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn conditional_parse_test() {
|
fn conditional_parse_test() {
|
||||||
use tokenizer;
|
use tokenizer;
|
||||||
use super::ASTNode::*;
|
|
||||||
use super::Expression::*;
|
|
||||||
|
|
||||||
let t1 = "if null then 20 else 40 end";
|
let t1 = "if null then 20 else 40 end";
|
||||||
let tokens = tokenizer::tokenize(t1).unwrap();
|
let tokens = tokenizer::tokenize(t1).unwrap();
|
||||||
match parse(&tokens, &[]).unwrap()[..] {
|
match parse(&tokens, &[]).unwrap()[..] {
|
||||||
|
Loading…
Reference in New Issue
Block a user