Finished initial BinOp/PrefixOp

This commit is contained in:
greg 2018-02-23 19:06:37 -08:00
parent 0dd8861f83
commit d229a57837
3 changed files with 51 additions and 8 deletions

View File

@ -0,0 +1,40 @@
use std::rc::Rc;
#[derive(Debug, PartialEq, Clone)]
pub struct BinOp {
pub sigil: Rc<String>
}
#[derive(Debug, PartialEq, Clone)]
pub struct PrefixOp {
pub sigil: Rc<String>
}
impl BinOp {
pub fn from_sigil(sigil: Rc<String>) -> BinOp {
BinOp { sigil }
}
pub fn min_precedence() -> i32 {
i32::min_value()
}
pub fn get_precedence(op: &str) -> i32 {
match op {
"+" | "-" => 10,
"*" | "/" | "%" => 20,
_ => 30,
}
}
}
impl PrefixOp {
pub fn from_sigil(sigil: Rc<String>) -> PrefixOp {
PrefixOp { sigil }
}
pub fn is_prefix(op: &str) -> bool {
match op {
"+" | "-" | "!" | "~" => true,
_ => false,
}
}
}

View File

@ -1,4 +1,5 @@
use schala_lang::parsing::{AST, Statement, Declaration, Expression, Variant, ExpressionType, Operation};
use schala_lang::parsing::{AST, Statement, Declaration, Expression, Variant, ExpressionType};
use schala_lang::builtin::{BinOp, PrefixOp};
use std::collections::HashMap;
use std::rc::Rc;
@ -162,12 +163,12 @@ impl State {
}
}
fn eval_binexp(&mut self, op: Operation, lhs: Box<Expression>, rhs: Box<Expression>) -> EvalResult<FullyEvaluatedExpr> {
fn eval_binexp(&mut self, op: BinOp, lhs: Box<Expression>, rhs: Box<Expression>) -> EvalResult<FullyEvaluatedExpr> {
use self::FullyEvaluatedExpr::*;
let evaled_lhs = self.eval_expr(*lhs)?;
let evaled_rhs = self.eval_expr(*rhs)?;
let opstr: &str = &op.0;
Ok(match (opstr, evaled_lhs, evaled_rhs) {
let sigil: &str = op.sigil.as_ref().as_str();
Ok(match (sigil, evaled_lhs, evaled_rhs) {
("+", UnsignedInt(l), UnsignedInt(r)) => UnsignedInt(l + r),
("++", Str(s1), Str(s2)) => Str(format!("{}{}", s1, s2)),
("-", UnsignedInt(l), UnsignedInt(r)) => UnsignedInt(l - r),
@ -178,12 +179,13 @@ impl State {
})
}
fn eval_prefix_exp(&mut self, op: Operation, expr: Box<Expression>) -> EvalResult<FullyEvaluatedExpr> {
fn eval_prefix_exp(&mut self, op: PrefixOp, expr: Box<Expression>) -> EvalResult<FullyEvaluatedExpr> {
use self::FullyEvaluatedExpr::*;
let evaled_expr = self.eval_expr(*expr)?;
let opstr: &str = &op.0;
Ok(match (opstr, evaled_expr) {
let sigil: &str = op.sigil.as_ref().as_str();
Ok(match (sigil, evaled_expr) {
("!", Bool(true)) => Bool(false),
("!", Bool(false)) => Bool(true),
("-", UnsignedInt(n)) => SignedInt(-1*(n as i64)),

View File

@ -2,6 +2,7 @@ use std::rc::Rc;
use std::collections::HashMap;
use schala_lang::parsing;
use schala_lang::builtin;
pub struct TypeContext {
bindings: HashMap<Rc<String>, Type>
@ -129,7 +130,7 @@ impl TypeContext {
_ => Err(format!("Type not yet implemented"))
}
}
fn infer_optype(&mut self, _op: &parsing::Operation) -> TypeResult<Type> {
fn infer_optype(&mut self, _op: &builtin::BinOp) -> TypeResult<Type> {
use self::Type::*; use self::TConst::*;
//this is a shim; not all ops are binops from int -> int -> int
Ok(Func(bx!(Const(Int)), bx!(Func(bx!(Const(Int)), bx!(Const(Int))))))