diff --git a/schala-lang/language/src/ast.rs b/schala-lang/language/src/ast.rs index a8e73a5..dd4840f 100644 --- a/schala-lang/language/src/ast.rs +++ b/schala-lang/language/src/ast.rs @@ -1,7 +1,6 @@ use std::rc::Rc; use std::convert::From; -use crate::builtin::{BinOp}; use crate::typechecking::TypeData; mod operators; diff --git a/schala-lang/language/src/ast/operators.rs b/schala-lang/language/src/ast/operators.rs index 64f4e2c..217a1a4 100644 --- a/schala-lang/language/src/ast/operators.rs +++ b/schala-lang/language/src/ast/operators.rs @@ -1,6 +1,7 @@ use std::rc::Rc; use std::str::FromStr; +use crate::tokenizing::TokenKind; use crate::builtin::Builtin; #[derive(Debug, PartialEq, Clone)] @@ -39,3 +40,72 @@ impl FromStr for PrefixOp { builtin.map(|builtin| PrefixOp { sigil: Rc::new(s.to_string()), builtin: Some(builtin) }) } } + +#[derive(Debug, PartialEq, Clone)] +pub struct BinOp { + sigil: Rc, + pub builtin: Option, +} + +impl BinOp { + pub fn from_sigil(sigil: &str) -> BinOp { + let builtin = Builtin::from_str(sigil).ok(); + BinOp { sigil: Rc::new(sigil.to_string()), builtin } + } + pub fn sigil(&self) -> &Rc { + &self.sigil + } + pub fn from_sigil_token(tok: &TokenKind) -> Option { + let s = token_kind_to_sigil(tok)?; + Some(BinOp::from_sigil(s)) + } + + pub fn min_precedence() -> i32 { + i32::min_value() + } + pub fn get_precedence_from_token(op_tok: &TokenKind) -> Option { + let s = token_kind_to_sigil(op_tok)?; + Some(binop_precedences(s)) + } + + pub fn get_precedence(&self) -> i32 { + binop_precedences(&self.sigil) + } +} + +fn token_kind_to_sigil<'a>(tok: &'a TokenKind) -> Option<&'a str> { + use self::TokenKind::*; + Some(match tok { + Operator(op) => op.as_str(), + Period => ".", + Pipe => "|", + Slash => "/", + LAngleBracket => "<", + RAngleBracket => ">", + Equals => "=", + _ => return None + }) +} + +fn binop_precedences(s: &str) -> i32 { + let default = 10_000_000; + match s { + "+" => 10, + "-" => 10, + "*" => 20, + "/" => 20, + "%" => 20, + "++" => 30, + "^" => 30, + "&" => 20, + "|" => 20, + ">" => 20, + ">=" => 20, + "<" => 20, + "<=" => 20, + "==" => 40, + "=" => 10, + "<=>" => 30, + _ => default, + } +} diff --git a/schala-lang/language/src/builtin.rs b/schala-lang/language/src/builtin.rs index afca3f7..09176cd 100644 --- a/schala-lang/language/src/builtin.rs +++ b/schala-lang/language/src/builtin.rs @@ -1,8 +1,5 @@ -use std::rc::Rc; -use std::collections::HashMap; use std::str::FromStr; -use crate::tokenizing::TokenKind; use crate::typechecking::{TypeConst, Type}; #[derive(Debug, Clone, Copy, PartialEq)] @@ -103,86 +100,3 @@ impl FromStr for Builtin { }) } } - -#[derive(Debug, PartialEq, Clone)] -pub struct BinOp { - sigil: Rc, - pub builtin: Option, -} - -fn token_kind_to_sigil<'a>(tok: &'a TokenKind) -> Option<&'a str> { - use self::TokenKind::*; - Some(match tok { - Operator(op) => op.as_str(), - Period => ".", - Pipe => "|", - Slash => "/", - LAngleBracket => "<", - RAngleBracket => ">", - Equals => "=", - _ => return None - }) -} - -impl BinOp { - pub fn from_sigil(sigil: &str) -> BinOp { - let builtin = Builtin::from_str(sigil).ok(); - BinOp { sigil: Rc::new(sigil.to_string()), builtin } - } - pub fn sigil(&self) -> &Rc { - &self.sigil - } - pub fn from_sigil_token(tok: &TokenKind) -> Option { - let s = token_kind_to_sigil(tok)?; - Some(BinOp::from_sigil(s)) - } - - pub fn min_precedence() -> i32 { - i32::min_value() - } - pub fn get_precedence_from_token(op_tok: &TokenKind) -> Option { - let s = token_kind_to_sigil(op_tok)?; - let default = 10_000_000; - Some(BINOPS.get(s).map(|x| x.2.clone()).unwrap_or_else(|| { - default - })) - } - - pub fn get_precedence(&self) -> i32 { - let s: &str = &self.sigil; - let default = 10_000_000; - BINOPS.get(s).map(|x| x.2.clone()).unwrap_or_else(|| { - default - }) - } -} - - -//TODO mapping between sigil string and precedence should live in ast.rs -//mapping between operation and type should live here in builtins.rs - -/* the second tuple member is a placeholder for when I want to make evaluation rules tied to the - * binop definition */ -//TODO some of these types are going to have to be adjusted -lazy_static! { - static ref BINOPS: HashMap<&'static str, (Type, (), i32)> = - hashmap! { - "+" => (ty!(Nat -> Nat -> Nat), (), 10), - "-" => (ty!(Nat -> Nat -> Nat), (), 10), - "*" => (ty!(Nat -> Nat -> Nat), (), 20), - "/" => (ty!(Nat -> Nat -> Float), (), 20), - "quot" => (ty!(Nat -> Nat -> Nat), (), 20), - "%" => (ty!(Nat -> Nat -> Nat), (), 20), - "++" => (ty!(StringT -> StringT -> StringT), (), 30), - "^" => (ty!(Nat -> Nat -> Nat), (), 20), - "&" => (ty!(Nat -> Nat -> Nat), (), 20), - "|" => (ty!(Nat -> Nat -> Nat), (), 20), - ">" => (ty!(Nat -> Nat -> Bool), (), 20), - ">=" => (ty!(Nat -> Nat -> Bool), (), 20), - "<" => (ty!(Nat -> Nat -> Bool), (), 20), - "<=" => (ty!(Nat -> Nat -> Bool), (), 20), - "==" => (ty!(Nat -> Nat -> Bool), (), 20), - "=" => (ty!(Unit), (), 20), //TODO not sure what the type of this should be b/c special fmr - "<=>" => (ty!(Nat -> Nat -> Ordering), (), 20), //TODO figure out how to treat Order - }; -} diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index 0b4e557..26b83a5 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -153,8 +153,6 @@ use crate::tokenizing::TokenKind::*; use crate::ast::*; -use crate::builtin::{BinOp}; - /// Represents a parsing error #[derive(Debug)] pub struct ParseError { diff --git a/schala-lang/language/src/parsing/test.rs b/schala-lang/language/src/parsing/test.rs index 85806a5..33363eb 100644 --- a/schala-lang/language/src/parsing/test.rs +++ b/schala-lang/language/src/parsing/test.rs @@ -4,8 +4,7 @@ use std::str::FromStr; use super::tokenize; use super::ParseResult; -use crate::builtin::{BinOp}; -use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp}; +use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp}; use super::Statement::*; use super::Declaration::*; use super::Signature; diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 02939fa..7302b26 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -17,7 +17,7 @@ use std::str::FromStr; use crate::ast::*; use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable}; -use crate::builtin::{BinOp, Builtin}; +use crate::builtin::Builtin; #[derive(Debug)] pub struct ReducedAST(pub Vec); diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index 7e7e73f..435f19d 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -5,7 +5,6 @@ use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyVal use crate::ast::*; use crate::util::ScopeStack; -use crate::builtin::{BinOp}; #[derive(Debug, Clone, PartialEq)]