Starting to munge BinOp types

Incomplete, doesn't yet compile
This commit is contained in:
greg 2018-02-23 04:10:00 -08:00
parent 36174140bc
commit 413c5afe67
2 changed files with 15 additions and 36 deletions

View File

@ -5,6 +5,7 @@ macro_rules! bx {
($e:expr) => { Box::new($e) } ($e:expr) => { Box::new($e) }
} }
mod builtin;
mod tokenizing; mod tokenizing;
mod parsing; mod parsing;

View File

@ -6,6 +6,8 @@ use schala_lang::tokenizing::*;
use schala_lang::tokenizing::Kw::*; use schala_lang::tokenizing::Kw::*;
use schala_lang::tokenizing::TokenType::*; use schala_lang::tokenizing::TokenType::*;
use schala_lang::builtin::{BinOp, PrefixOp};
/* Schala EBNF Grammar */ /* Schala EBNF Grammar */
/* Terminal productions are in 'single quotes' or UPPERCASE if they are a class /* Terminal productions are in 'single quotes' or UPPERCASE if they are a class
* or not representable in ASCII * or not representable in ASCII
@ -224,8 +226,8 @@ pub enum ExpressionType {
FloatLiteral(f64), FloatLiteral(f64),
StringLiteral(Rc<String>), StringLiteral(Rc<String>),
BoolLiteral(bool), BoolLiteral(bool),
BinExp(Operation, Box<Expression>, Box<Expression>), BinExp(BinOp, Box<Expression>, Box<Expression>),
PrefixExp(Operation, Box<Expression>), PrefixExp(PrefixOp, Box<Expression>),
TupleLiteral(Vec<Expression>), TupleLiteral(Vec<Expression>),
Value(Rc<String>, Vec<(Rc<String>, Expression)>), Value(Rc<String>, Vec<(Rc<String>, Expression)>),
Call { Call {
@ -250,30 +252,6 @@ pub struct MatchArm {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Pattern(Rc<String>); pub struct Pattern(Rc<String>);
#[derive(Debug, PartialEq, Clone)]
pub struct Operation(pub Rc<String>);
impl Operation {
fn min_precedence() -> i32 {
i32::min_value()
}
fn get_precedence(op: &str) -> i32 {
match op {
"+" | "-" => 10,
"*" | "/" | "%" => 20,
_ => 30,
}
}
fn is_prefix(op: &str) -> bool {
match op {
"+" | "-" | "!" | "~" => true,
_ => false,
}
}
}
macro_rules! parse_method { macro_rules! parse_method {
($name:ident(&mut $self:ident) -> $type:ty $body:block) => { ($name:ident(&mut $self:ident) -> $type:ty $body:block) => {
fn $name(&mut $self) -> $type { fn $name(&mut $self) -> $type {
@ -504,7 +482,7 @@ impl Parser {
}); });
parse_method!(expression(&mut self) -> ParseResult<Expression> { parse_method!(expression(&mut self) -> ParseResult<Expression> {
let mut expr_body = self.precedence_expr(Operation::min_precedence())?; let mut expr_body = self.precedence_expr(BinOp::min_precedence())?;
let type_anno = match self.peek() { let type_anno = match self.peek() {
Colon => Some(self.type_anno()?), Colon => Some(self.type_anno()?),
_ => None _ => None
@ -553,21 +531,21 @@ impl Parser {
let mut lhs = self.prefix_expr()?; let mut lhs = self.prefix_expr()?;
loop { loop {
let new_precedence = match self.peek() { let new_precedence = match self.peek() {
Operator(op) => Operation::get_precedence(&*op), Operator(op) => BinOp::get_precedence(&*op),
Period => Operation::get_precedence("."), Period => BinOp::get_precedence("."),
_ => break, _ => break,
}; };
if precedence >= new_precedence { if precedence >= new_precedence {
break; break;
} }
let op_str = match self.next() { let sigil = match self.next() {
Operator(op) => op, Operator(op) => op,
Period => Rc::new(".".to_string()), Period => Rc::new(".".to_string()),
_ => unreachable!(), _ => unreachable!(),
}; };
let rhs = self.precedence_expr(new_precedence)?; let rhs = self.precedence_expr(new_precedence)?;
let operation = Operation(op_str); let operation = BinOp::from_sigil(sigil);
lhs = Expression(ExpressionType::BinExp(operation, bx!(lhs), bx!(rhs)), None); lhs = Expression(ExpressionType::BinExp(operation, bx!(lhs), bx!(rhs)), None);
} }
self.parse_level -= 1; self.parse_level -= 1;
@ -576,14 +554,14 @@ impl Parser {
parse_method!(prefix_expr(&mut self) -> ParseResult<Expression> { parse_method!(prefix_expr(&mut self) -> ParseResult<Expression> {
match self.peek() { match self.peek() {
Operator(ref op) if Operation::is_prefix(&*op) => { Operator(ref op) if PrefixOp::is_prefix(&*op) => {
let op_str = match self.next() { let sigil = match self.next() {
Operator(op) => op, Operator(op) => op,
_ => unreachable!(), _ => unreachable!(),
}; };
let expr = self.primary()?; let expr = self.primary()?;
Ok(Expression( Ok(Expression(
ExpressionType::PrefixExp(Operation(op_str), bx!(expr)), ExpressionType::PrefixExp(PrefixOp::from_sigil(sigil), bx!(expr)),
None)) None))
}, },
_ => self.primary() _ => self.primary()
@ -852,7 +830,7 @@ pub fn parse(input: Vec<Token>) -> (Result<AST, ParseError>, Vec<String>) {
#[cfg(test)] #[cfg(test)]
mod parse_tests { mod parse_tests {
use ::std::rc::Rc; use ::std::rc::Rc;
use super::{AST, Expression, Statement, Operation, TypeBody, Variant, parse, tokenize}; use super::{AST, Expression, Statement, PrefixOp, BinOp, TypeBody, Variant, parse, tokenize};
use super::Statement::*; use super::Statement::*;
use super::Declaration::*; use super::Declaration::*;
use super::Signature; use super::Signature;
@ -877,7 +855,7 @@ mod parse_tests {
($op:expr, $lhs:expr) => { PrefixExp(op!($op), bx!(Expression($lhs, None))) } ($op:expr, $lhs:expr) => { PrefixExp(op!($op), bx!(Expression($lhs, None))) }
} }
macro_rules! op { macro_rules! op {
($op:expr) => { Operation(Rc::new($op.to_string())) } ($op:expr) => { BinOp::from_sigil($op.to_string()) }
} }
macro_rules! val { macro_rules! val {
($var:expr) => { Value(Rc::new($var.to_string()), vec![]) } ($var:expr) => { Value(Rc::new($var.to_string()), vec![]) }