Change where Builtin is calculated from operators

This commit is contained in:
Greg Shuflin 2021-10-16 20:21:08 -07:00
parent 25bffa339c
commit 2fe4109296
7 changed files with 48 additions and 34 deletions

View File

@ -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;

View File

@ -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))

View File

@ -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 = ();

View File

@ -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))

View File

@ -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())) };

View File

@ -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)] }

View File

@ -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"),
};