Starting to munge BinOp types
Incomplete, doesn't yet compile
This commit is contained in:
parent
4ab900d601
commit
0dd8861f83
@ -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;
|
||||||
|
@ -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![]) }
|
||||||
|
Loading…
Reference in New Issue
Block a user