aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/grammar.pest2
-rw-r--r--src/main.rs251
2 files changed, 100 insertions, 153 deletions
diff --git a/src/grammar.pest b/src/grammar.pest
index 822e256..000ddd5 100644
--- a/src/grammar.pest
+++ b/src/grammar.pest
@@ -1,7 +1,7 @@
COMMENT = _{ "#" ~ (!("#" | NEWLINE) ~ ANY)* ~ NEWLINE* }
WHITESPACE = _{ " " | "\t" | NEWLINE }
program = { SOI ~ statement+ ~ EOI }
-statement = { (definition | expression)}
+statement = { (definition | expression) }
definition = { symbol ~ "=" ~ expression ~ ";"+ }
expression = { (symbol | integer_literal | string_literal | ("(" ~ expression ~ ")"))+ }
integer_literal = @{ "-"? ~ ASCII_DIGIT+ }
diff --git a/src/main.rs b/src/main.rs
index 41b4422..add9f5e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,6 @@
#[macro_use]
extern crate pest_derive;
-extern crate from_pest;
#[macro_use]
-extern crate pest_ast;
extern crate pest;
mod parser {
@@ -11,173 +9,122 @@ mod parser {
pub struct Parser;
}
-// mod ast {
-// use super::parser::Rule;
-// use pest::Span;
+mod ast {
+ use super::parser::Rule;
+ use pest::Span;
-// fn span_into_str(span: Span) -> &str {
-// span.as_str()
-// }
+ fn span_into_str(span: Span) -> &str {
+ span.as_str()
+ }
-// #[derive(Debug, FromPest)]
-// #[pest_ast(rule(Rule::program))]
-// pub struct Program {
-// pub statements: Vec<Statement>,
-// pub eoi: EOI,
-// }
+ pub fn from_parse_tree(parse_tree: &mut pest::iterators::Pairs<Rule>) -> Program {
+ let root = parse_tree.next().unwrap();
-// #[derive(Debug, FromPest)]
-// #[pest_ast(rule(Rule::statement))]
-// pub enum Statement {
-// Definition(Definition),
-// Expression(Expression),
-// }
+ match root.as_rule() {
+ Rule::program => {
+ let statements_with_eoi: Vec<pest::iterators::Pair<Rule>> =
+ root.into_inner().collect();
+ let statements_split = statements_with_eoi.split_last().unwrap();
+ let statements = statements_split.1.to_vec();
-// #[derive(Debug, FromPest)]
-// #[pest_ast(rule(Rule::definition))]
-// pub struct Definition {
-// pub symbols: Vec<Symbol>,
-// pub expression: Expression,
-// }
+ statements
+ .iter()
+ .map(|s| Statement::from_pair(s.clone()))
+ .collect()
+ }
+ _ => panic!("[ast] first Pair is not a program"),
+ }
+ }
-// #[derive(Debug, FromPest, Clone)]
-// #[pest_ast(rule(Rule::expression))]
-// pub enum Expression {
-// IntegerLiteral(IntegerLiteral),
-// Symbol(Symbol),
-// SubExpressions(Vec<Expression>),
-// }
+ pub type Program = Vec<Statement>;
-// #[derive(Debug, FromPest, Copy, Clone)]
-// #[pest_ast(rule(Rule::integer_literal))]
-// pub struct IntegerLiteral {
-// #[pest_ast(outer(with(span_into_str), with(str::parse::<i64>), with(Result::unwrap)))]
-// pub value: i64,
-// }
+ #[derive(Debug)]
+ pub enum Statement {
+ Definition {
+ symbol: Symbol,
+ expression: Expression,
+ },
+ Expression(Expression),
+ }
-// #[derive(Debug, FromPest, Clone)]
-// #[pest_ast(rule(Rule::symbol))]
-// pub struct Symbol {
-// #[pest_ast(outer(with(span_into_str), with(String::from)))]
-// pub value: String,
-// }
+ impl Statement {
+ fn from_pair(pair: pest::iterators::Pair<Rule>) -> Statement {
+ // println!("Statement::from_pair pair: {:#?}", pair);
+ let def_or_expr = pair.into_inner().next().unwrap();
-// #[derive(Debug, FromPest, Copy, Clone)]
-// #[pest_ast(rule(Rule::EOI))]
-// pub struct EOI;
-// }
+ fn definition_from_pair(pair: pest::iterators::Pair<Rule>) -> Statement {
+ let mut inner = pair.into_inner();
+ let symbol = inner.next().unwrap().as_span().as_str();
+ let expression = inner.next().unwrap();
+ let expression_inners: Vec<ExpressionInner> = expression
+ .into_inner()
+ .map(ExpressionInner::from_pair)
+ .collect();
-// mod ir {
-// use super::ast;
+ Statement::Definition {
+ symbol: String::from(symbol),
+ expression: expression_inners,
+ }
+ }
-// pub fn left_associate_exprs(program: &ast::Program) -> ast::Program {
-// fn associate(expr: &ast::Expression) -> ast::Expression {
-// match expr.nodes.len() {
-// 1 | 2 => expr.clone(),
-// 3.. => {
-// let inner_node = ast::ExpressionNode::SubNodes(expr.nodes[0..2].to_vec());
-// let rest = expr.nodes[2..].to_vec();
-// let mut new_nodes = vec![inner_node];
-// new_nodes.extend(rest);
-// let outer_node = ast::Expression { nodes: new_nodes };
-// associate(&outer_node)
-// }
-// _ => unreachable!(),
-// }
-// }
+ match def_or_expr.as_rule() {
+ Rule::definition => definition_from_pair(def_or_expr),
+ Rule::expression => {
+ let expression_inners: Vec<ExpressionInner> = def_or_expr
+ .into_inner()
+ .map(ExpressionInner::from_pair)
+ .collect();
+ Statement::Expression(expression_inners)
+ }
+ rule => panic!("[ast] can't make a statement from {:#?}", rule),
+ }
+ }
+ }
-// let statements = program
-// .statements
-// .iter()
-// .map(|s| match s {
-// ast::Statement::Expression(expr) => ast::Statement::Expression(associate(expr)),
-// ast::Statement::Definition(def) => ast::Statement::Definition(ast::Definition {
-// symbols: def.symbols.clone(),
-// expression: associate(&def.expression),
-// }),
-// })
-// .collect();
+ #[derive(Debug)]
+ pub enum ExpressionInner {
+ Symbol(Symbol),
+ IntegerLiteral(IntegerLiteral),
+ StringLiteral(StringLiteral),
+ Expression(Expression),
+ }
-// ast::Program {
-// statements,
-// eoi: program.eoi.clone(),
-// }
-// }
-// }
+ impl ExpressionInner {
+ fn from_pair(pair: pest::iterators::Pair<Rule>) -> ExpressionInner {
+ // println!("ExpressionInner::from_pair pair: {:#?}", pair);
-// mod runtime {
-// use super::ast;
-// use std::collections::HashMap;
-// use std::rc::Rc;
+ match pair.as_rule() {
+ Rule::symbol => ExpressionInner::Symbol(string_from_pair(pair)),
+ Rule::integer_literal => ExpressionInner::IntegerLiteral(integer_from_pair(pair)),
+ Rule::string_literal => ExpressionInner::StringLiteral(string_from_pair(pair)),
+ Rule::expression => {
+ let expression_inners: Vec<ExpressionInner> =
+ pair.into_inner().map(ExpressionInner::from_pair).collect();
+ ExpressionInner::Expression(expression_inners)
+ }
+ rule => panic!("[ast] can't make an expression element from {:#?}", rule),
+ }
+ }
+ }
-// #[derive(Debug)]
-// pub enum BuiltinFn {
-// Const(i64),
-// }
+ pub type Expression = Vec<ExpressionInner>;
-// #[derive(Debug)]
-// pub enum Function {
-// Builtin(BuiltinFn),
-// }
+ pub type IntegerLiteral = i64;
+ fn integer_from_pair(pair: pest::iterators::Pair<Rule>) -> i64 {
+ let s = pair.as_span().as_str();
+ s.parse().unwrap()
+ }
-// pub fn evaluate(ast: &ast::Program) {
-// let mut symbol_table: HashMap<String, Rc<Function>> = HashMap::new();
+ pub type StringLiteral = String;
+ fn string_from_pair(pair: pest::iterators::Pair<Rule>) -> String {
+ String::from(pair.as_span().as_str())
+ }
-// // symbol_table.insert(String::from("const"));
-
-// // fn apply_function(function: &Function, arg: &Function) -> Function {
-// // match function {
-// // Function::Builtin(builtin_fn) => match builtin_fn {
-// // BuiltinFn::Const(value) => Function::Builtin(BuiltinFn::Const(*value)),
-// // },
-// // }
-// // }
-
-// fn evaluate_nonary(
-// table: &HashMap<String, Rc<Function>>,
-// lhs: &ast::ExpressionNode,
-// ) -> Rc<Function> {
-// match lhs {
-// ast::ExpressionNode::IntegerLiteral(literal) => {
-// Rc::new(Function::Builtin(BuiltinFn::Const(literal.value)))
-// }
-// ast::ExpressionNode::Symbol(symbol) => match symbol.value.as_str() {
-// "math-zero" => Rc::new(Function::Builtin(BuiltinFn::Const(0))),
-// sym => (*table.get(sym).expect("symbol not found")).clone(),
-// },
-// _ => todo!("_ case in evaluate_nonary"),
-// }
-// }
-
-// fn evaluate_unary(
-// table: &HashMap<String, Rc<Function>>,
-// lhs: &ast::ExpressionNode,
-// rhs: &ast::ExpressionNode,
-// ) -> Rc<Function> {
-// let rhs_evaled = evaluate_nonary(&table, rhs);
-// todo!("evaluate_unary")
-// }
-
-// for statement in &ast.statements {
-// let res: Rc<Function> = match statement {
-// ast::Statement::Expression(expression) => match expression.nodes.len() {
-// 1 => evaluate_nonary(&symbol_table, &expression.nodes[0]),
-// 2 => evaluate_unary(&symbol_table, &expression.nodes[0], &expression.nodes[1]),
-// _ => unreachable!("expr arity > 2"),
-// },
-// ast::Statement::Definition(_) => {
-// panic!("unsupported statement type: definition")
-// }
-// };
-
-// println!("Result: {:#?}", res)
-// }
-// }
-// }
+ pub type Symbol = String;
+}
fn main() {
- // use ast::Program;
- use from_pest::FromPest;
+ use ast::Program;
use pest::Parser;
use std::fs;
@@ -186,8 +133,8 @@ fn main() {
parser::Parser::parse(parser::Rule::program, &unparsed_file).expect("unsuccessful parse");
println!("parse tree = {:#?}", parse_tree);
- // let syntax_tree: Program = Program::from_pest(&mut parse_tree).expect("infallible");
- // println!("syntax tree = {:#?}", syntax_tree);
+ let syntax_tree: Program = ast::from_parse_tree(&mut parse_tree);
+ println!("syntax tree = {:#?}", syntax_tree);
// let ir_tree = ir::left_associate_exprs(&syntax_tree);
// println!("ir tree = {:#?}", ir_tree);