Change where Builtin is calculated from operators
This commit is contained in:
parent
25bffa339c
commit
2fe4109296
@ -6,7 +6,7 @@ mod walker;
|
||||
mod visitor;
|
||||
mod visitor_test;
|
||||
mod operators;
|
||||
pub use operators::*;
|
||||
pub use operators::{PrefixOp, BinOp};
|
||||
pub use visitor::ASTVisitor;
|
||||
pub use walker::walk_ast;
|
||||
use crate::tokenizing::Location;
|
||||
|
@ -1,20 +1,21 @@
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::tokenizing::TokenKind;
|
||||
use crate::builtin::Builtin;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct PrefixOp {
|
||||
sigil: Rc<String>,
|
||||
pub builtin: Option<Builtin>,
|
||||
}
|
||||
|
||||
impl PrefixOp {
|
||||
#[allow(dead_code)]
|
||||
pub fn sigil(&self) -> &Rc<String> {
|
||||
pub fn from_sigil(sigil: &str) -> PrefixOp {
|
||||
PrefixOp { sigil: Rc::new(sigil.to_string()) }
|
||||
}
|
||||
|
||||
pub fn sigil(&self) -> &str {
|
||||
&self.sigil
|
||||
}
|
||||
|
||||
pub fn is_prefix(op: &str) -> bool {
|
||||
match op {
|
||||
"+" => true,
|
||||
@ -25,37 +26,20 @@ impl PrefixOp {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for PrefixOp {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use Builtin::*;
|
||||
|
||||
let builtin = match s {
|
||||
"+" => Ok(Increment),
|
||||
"-" => Ok(Negate),
|
||||
"!" => Ok(BooleanNot),
|
||||
_ => Err(())
|
||||
};
|
||||
|
||||
builtin.map(|builtin| PrefixOp { sigil: Rc::new(s.to_string()), builtin: Some(builtin) })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct BinOp {
|
||||
sigil: Rc<String>,
|
||||
pub builtin: Option<Builtin>,
|
||||
}
|
||||
|
||||
impl BinOp {
|
||||
pub fn from_sigil(sigil: &str) -> BinOp {
|
||||
let builtin = Builtin::from_str(sigil).ok();
|
||||
BinOp { sigil: Rc::new(sigil.to_string()), builtin }
|
||||
BinOp { sigil: Rc::new(sigil.to_string()) }
|
||||
}
|
||||
pub fn sigil(&self) -> &Rc<String> {
|
||||
|
||||
pub fn sigil(&self) -> &str {
|
||||
&self.sigil
|
||||
}
|
||||
|
||||
pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> {
|
||||
let s = token_kind_to_sigil(tok)?;
|
||||
Some(BinOp::from_sigil(s))
|
||||
|
@ -1,7 +1,10 @@
|
||||
use std::str::FromStr;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use crate::typechecking::{TypeConst, Type};
|
||||
use crate::ast::{BinOp, PrefixOp};
|
||||
|
||||
/// "Builtin" computational operations with some kind of semantics, mostly mathematical operations.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Builtin {
|
||||
Add,
|
||||
@ -66,6 +69,29 @@ impl Builtin {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&BinOp> for Builtin {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(binop: &BinOp) -> Result<Self, Self::Error> {
|
||||
FromStr::from_str(binop.sigil())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&PrefixOp> for Builtin {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(prefix_op: &PrefixOp) -> Result<Self, Self::Error> {
|
||||
use Builtin::*;
|
||||
|
||||
match prefix_op.sigil() {
|
||||
"+" => Ok(Increment),
|
||||
"-" => Ok(Negate),
|
||||
"!" => Ok(BooleanNot),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Builtin {
|
||||
type Err = ();
|
||||
|
||||
|
@ -161,7 +161,6 @@
|
||||
mod test;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::tokenizing::*;
|
||||
use crate::tokenizing::Kw::*;
|
||||
@ -658,7 +657,7 @@ impl Parser {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let expr = self.primary()?;
|
||||
let prefix_op = PrefixOp::from_str(sigil.as_str()).unwrap();
|
||||
let prefix_op = PrefixOp::from_sigil(sigil.as_str());
|
||||
Ok(Expression::new(
|
||||
self.id_store.fresh(),
|
||||
ExpressionKind::PrefixExp(prefix_op, Box::new(expr))
|
||||
|
@ -1,6 +1,5 @@
|
||||
#![cfg(test)]
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::tokenizing::Location;
|
||||
use super::{Parser, ParseResult, tokenize};
|
||||
@ -109,7 +108,7 @@ macro_rules! binexp {
|
||||
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into()), bx!(Expression::new(ItemIdStore::new_id(), $rhs).into())) }
|
||||
}
|
||||
macro_rules! prefexp {
|
||||
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into())) }
|
||||
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into())) }
|
||||
}
|
||||
macro_rules! exst {
|
||||
($expr_type:expr) => { make_statement(StatementKind::Expression(Expression::new(ItemIdStore::new_id(), $expr_type).into())) };
|
||||
|
@ -14,6 +14,7 @@
|
||||
//! built from the ReducedAST.
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable, FullyQualifiedSymbolName};
|
||||
@ -337,7 +338,8 @@ impl<'a> Reducer<'a> {
|
||||
}
|
||||
|
||||
fn prefix(&mut self, prefix: &PrefixOp, arg: &Box<Expression>) -> Expr {
|
||||
match prefix.builtin {
|
||||
let builtin: Option<Builtin> = TryFrom::try_from(prefix).ok();
|
||||
match builtin {
|
||||
Some(op) => {
|
||||
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
|
||||
Expr::Call { f, args: vec![self.expression(arg)] }
|
||||
|
@ -1,8 +1,10 @@
|
||||
use std::rc::Rc;
|
||||
use std::fmt::Write;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyValue};
|
||||
|
||||
use crate::builtin::Builtin;
|
||||
use crate::ast::*;
|
||||
use crate::util::ScopeStack;
|
||||
use crate::util::deref_optional_box;
|
||||
@ -332,7 +334,8 @@ impl<'a> TypeContext<'a> {
|
||||
}
|
||||
|
||||
fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> {
|
||||
let tf = match op.builtin.map(|b| b.get_type()) {
|
||||
let builtin: Option<Builtin> = TryFrom::try_from(op).ok();
|
||||
let tf = match builtin.map(|b| b.get_type()) {
|
||||
Some(ty) => ty,
|
||||
None => return TypeError::new("no type found")
|
||||
};
|
||||
@ -342,7 +345,8 @@ impl<'a> TypeContext<'a> {
|
||||
}
|
||||
|
||||
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> InferResult<Type> {
|
||||
let tf = match op.builtin.map(|b| b.get_type()) {
|
||||
let builtin: Option<Builtin> = TryFrom::try_from(op).ok();
|
||||
let tf = match builtin.map(|b| b.get_type()) {
|
||||
Some(ty) => ty,
|
||||
None => return TypeError::new("no type found"),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user