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;
|
||||||
mod visitor_test;
|
mod visitor_test;
|
||||||
mod operators;
|
mod operators;
|
||||||
pub use operators::*;
|
pub use operators::{PrefixOp, BinOp};
|
||||||
pub use visitor::ASTVisitor;
|
pub use visitor::ASTVisitor;
|
||||||
pub use walker::walk_ast;
|
pub use walker::walk_ast;
|
||||||
use crate::tokenizing::Location;
|
use crate::tokenizing::Location;
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::tokenizing::TokenKind;
|
use crate::tokenizing::TokenKind;
|
||||||
use crate::builtin::Builtin;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct PrefixOp {
|
pub struct PrefixOp {
|
||||||
sigil: Rc<String>,
|
sigil: Rc<String>,
|
||||||
pub builtin: Option<Builtin>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrefixOp {
|
impl PrefixOp {
|
||||||
#[allow(dead_code)]
|
pub fn from_sigil(sigil: &str) -> PrefixOp {
|
||||||
pub fn sigil(&self) -> &Rc<String> {
|
PrefixOp { sigil: Rc::new(sigil.to_string()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sigil(&self) -> &str {
|
||||||
&self.sigil
|
&self.sigil
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_prefix(op: &str) -> bool {
|
pub fn is_prefix(op: &str) -> bool {
|
||||||
match op {
|
match op {
|
||||||
"+" => true,
|
"+" => 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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct BinOp {
|
pub struct BinOp {
|
||||||
sigil: Rc<String>,
|
sigil: Rc<String>,
|
||||||
pub builtin: Option<Builtin>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinOp {
|
impl BinOp {
|
||||||
pub fn from_sigil(sigil: &str) -> BinOp {
|
pub fn from_sigil(sigil: &str) -> BinOp {
|
||||||
let builtin = Builtin::from_str(sigil).ok();
|
BinOp { sigil: Rc::new(sigil.to_string()) }
|
||||||
BinOp { sigil: Rc::new(sigil.to_string()), builtin }
|
|
||||||
}
|
}
|
||||||
pub fn sigil(&self) -> &Rc<String> {
|
|
||||||
|
pub fn sigil(&self) -> &str {
|
||||||
&self.sigil
|
&self.sigil
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> {
|
pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> {
|
||||||
let s = token_kind_to_sigil(tok)?;
|
let s = token_kind_to_sigil(tok)?;
|
||||||
Some(BinOp::from_sigil(s))
|
Some(BinOp::from_sigil(s))
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use crate::typechecking::{TypeConst, Type};
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Builtin {
|
pub enum Builtin {
|
||||||
Add,
|
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 {
|
impl FromStr for Builtin {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
|
@ -161,7 +161,6 @@
|
|||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::tokenizing::*;
|
use crate::tokenizing::*;
|
||||||
use crate::tokenizing::Kw::*;
|
use crate::tokenizing::Kw::*;
|
||||||
@ -658,7 +657,7 @@ impl Parser {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let expr = self.primary()?;
|
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(
|
Ok(Expression::new(
|
||||||
self.id_store.fresh(),
|
self.id_store.fresh(),
|
||||||
ExpressionKind::PrefixExp(prefix_op, Box::new(expr))
|
ExpressionKind::PrefixExp(prefix_op, Box::new(expr))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::tokenizing::Location;
|
use crate::tokenizing::Location;
|
||||||
use super::{Parser, ParseResult, tokenize};
|
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())) }
|
($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 {
|
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 {
|
macro_rules! exst {
|
||||||
($expr_type:expr) => { make_statement(StatementKind::Expression(Expression::new(ItemIdStore::new_id(), $expr_type).into())) };
|
($expr_type:expr) => { make_statement(StatementKind::Expression(Expression::new(ItemIdStore::new_id(), $expr_type).into())) };
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
//! built from the ReducedAST.
|
//! built from the ReducedAST.
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable, FullyQualifiedSymbolName};
|
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 {
|
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) => {
|
Some(op) => {
|
||||||
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
|
let f = Box::new(Expr::Func(Func::BuiltIn(op)));
|
||||||
Expr::Call { f, args: vec![self.expression(arg)] }
|
Expr::Call { f, args: vec![self.expression(arg)] }
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyValue};
|
use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyValue};
|
||||||
|
|
||||||
|
use crate::builtin::Builtin;
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::util::ScopeStack;
|
use crate::util::ScopeStack;
|
||||||
use crate::util::deref_optional_box;
|
use crate::util::deref_optional_box;
|
||||||
@ -332,7 +334,8 @@ impl<'a> TypeContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> {
|
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,
|
Some(ty) => ty,
|
||||||
None => return TypeError::new("no type found")
|
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> {
|
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,
|
Some(ty) => ty,
|
||||||
None => return TypeError::new("no type found"),
|
None => return TypeError::new("no type found"),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user