mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge branch 'trunk' of github.com:rtfeldman/roc into rust61
This commit is contained in:
commit
7c93d237ce
1077 changed files with 1235 additions and 3053 deletions
161
crates/compiler/module/src/called_via.rs
Normal file
161
crates/compiler/module/src/called_via.rs
Normal file
|
@ -0,0 +1,161 @@
|
|||
use self::BinOp::*;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum CalledVia {
|
||||
/// Calling with space, e.g. (foo bar)
|
||||
Space,
|
||||
|
||||
/// Calling with an operator, e.g. (bar |> foo) or (1 + 2)
|
||||
BinOp(BinOp),
|
||||
|
||||
/// Calling with a unary operator, e.g. (!foo bar baz) or (-foo bar baz)
|
||||
UnaryOp(UnaryOp),
|
||||
|
||||
/// This call is the result of desugaring string interpolation,
|
||||
/// e.g. "\(first) \(last)" is transformed into Str.concat (Str.concat first " ") last.
|
||||
StringInterpolation,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum UnaryOp {
|
||||
/// (-), e.g. (-x)
|
||||
Negate,
|
||||
/// (!), e.g. (!x)
|
||||
Not,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum BinOp {
|
||||
// highest precedence
|
||||
Caret,
|
||||
Star,
|
||||
Slash,
|
||||
DoubleSlash,
|
||||
Percent,
|
||||
Plus,
|
||||
Minus,
|
||||
Equals,
|
||||
NotEquals,
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
LessThanOrEq,
|
||||
GreaterThanOrEq,
|
||||
And,
|
||||
Or,
|
||||
Pizza,
|
||||
Assignment,
|
||||
IsAliasType,
|
||||
IsOpaqueType,
|
||||
Backpassing,
|
||||
// lowest precedence
|
||||
}
|
||||
|
||||
impl BinOp {
|
||||
/// how wide this operator is when typed out
|
||||
pub fn width(self) -> u16 {
|
||||
match self {
|
||||
Caret | Star | Slash | Percent | Plus | Minus | LessThan | GreaterThan => 1,
|
||||
DoubleSlash | Equals | NotEquals | LessThanOrEq | GreaterThanOrEq | And | Or
|
||||
| Pizza => 2,
|
||||
Assignment | IsAliasType | IsOpaqueType | Backpassing => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ArgSide {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Associativity {
|
||||
/// left-associative operators:
|
||||
///
|
||||
/// arithmetic: * / // % + -
|
||||
/// application: |>
|
||||
LeftAssociative,
|
||||
|
||||
/// right-associative operators:
|
||||
///
|
||||
/// exponentiation: ^
|
||||
/// boolean: && ||
|
||||
/// application: <|
|
||||
RightAssociative,
|
||||
|
||||
/// non-associative operators:
|
||||
///
|
||||
/// comparison: == > >= < <=
|
||||
NonAssociative,
|
||||
}
|
||||
|
||||
impl BinOp {
|
||||
pub fn associativity(self) -> Associativity {
|
||||
use self::Associativity::*;
|
||||
|
||||
match self {
|
||||
Pizza | Star | Slash | DoubleSlash | Percent | Plus | Minus => LeftAssociative,
|
||||
And | Or | Caret => RightAssociative,
|
||||
Equals | NotEquals | LessThan | GreaterThan | LessThanOrEq | GreaterThanOrEq => {
|
||||
NonAssociative
|
||||
}
|
||||
Assignment | IsAliasType | IsOpaqueType | Backpassing => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn precedence(self) -> u8 {
|
||||
match self {
|
||||
Caret => 7,
|
||||
Star | Slash | DoubleSlash | Percent => 6,
|
||||
Plus | Minus => 5,
|
||||
Equals | NotEquals | LessThan | GreaterThan | LessThanOrEq | GreaterThanOrEq => 4,
|
||||
And => 3,
|
||||
Or => 2,
|
||||
Pizza => 1,
|
||||
Assignment | IsAliasType | IsOpaqueType | Backpassing => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for BinOp {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for BinOp {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.precedence().cmp(&other.precedence())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BinOp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let as_str = match self {
|
||||
Caret => "^",
|
||||
Star => "*",
|
||||
Slash => "/",
|
||||
DoubleSlash => "//",
|
||||
Percent => "%",
|
||||
Plus => "+",
|
||||
Minus => "-",
|
||||
Equals => "==",
|
||||
NotEquals => "!=",
|
||||
LessThan => "<",
|
||||
GreaterThan => ">",
|
||||
LessThanOrEq => "<=",
|
||||
GreaterThanOrEq => ">=",
|
||||
And => "&&",
|
||||
Or => "||",
|
||||
Pizza => "|>",
|
||||
Assignment => "=",
|
||||
IsAliasType => ":",
|
||||
IsOpaqueType => ":=",
|
||||
Backpassing => "<-",
|
||||
};
|
||||
|
||||
write!(f, "{}", as_str)
|
||||
}
|
||||
}
|
298
crates/compiler/module/src/ident.rs
Normal file
298
crates/compiler/module/src/ident.rs
Normal file
|
@ -0,0 +1,298 @@
|
|||
pub use roc_ident::IdentStr;
|
||||
use std::fmt;
|
||||
|
||||
/// This could be uppercase or lowercase, qualified or unqualified.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
|
||||
pub struct Ident(pub IdentStr);
|
||||
|
||||
impl Ident {
|
||||
pub fn as_inline_str(&self) -> &IdentStr {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct QualifiedModuleName<'a> {
|
||||
pub opt_package: Option<&'a str>,
|
||||
pub module: ModuleName,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ModuleName(IdentStr);
|
||||
|
||||
impl std::ops::Deref for ModuleName {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
/// An uncapitalized identifier, such as a field name or local variable
|
||||
#[derive(Clone, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Lowercase(IdentStr);
|
||||
|
||||
/// A capitalized identifier, such as a tag name or module name
|
||||
#[derive(Clone, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Uppercase(IdentStr);
|
||||
|
||||
/// A string representing a foreign (linked-in) symbol
|
||||
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
|
||||
pub struct ForeignSymbol(IdentStr);
|
||||
|
||||
pub type TagIdIntType = u16;
|
||||
|
||||
/// Tags have no module, but tend to be short strings (since they're
|
||||
/// never qualified), so we store them as ident strings.
|
||||
///
|
||||
/// This is allows canonicalization to happen in parallel without locks.
|
||||
/// If tags had a Symbol representation, then each module would have to
|
||||
/// deal with contention on a global mutex around translating tag strings
|
||||
/// into integers. (Record field labels work the same way, for the same reason.)
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct TagName(pub Uppercase);
|
||||
|
||||
roc_error_macros::assert_sizeof_non_wasm!(TagName, 16);
|
||||
roc_error_macros::assert_sizeof_wasm!(TagName, 8);
|
||||
|
||||
impl TagName {
|
||||
pub fn as_ident_str(&self) -> IdentStr {
|
||||
self.0.as_ident_str().clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleName {
|
||||
// NOTE: After adding one of these, go to `impl ModuleId` and
|
||||
// add a corresponding ModuleId to there!
|
||||
pub const APP: &'static str = "#UserApp"; // app modules have this hardcoded name
|
||||
pub const BOOL: &'static str = "Bool";
|
||||
pub const STR: &'static str = "Str";
|
||||
pub const NUM: &'static str = "Num";
|
||||
pub const LIST: &'static str = "List";
|
||||
pub const DICT: &'static str = "Dict";
|
||||
pub const SET: &'static str = "Set";
|
||||
pub const RESULT: &'static str = "Result";
|
||||
pub const BOX: &'static str = "Box";
|
||||
pub const ENCODE: &'static str = "Encode";
|
||||
pub const JSON: &'static str = "Json";
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
pub fn as_ident_str(&self) -> &IdentStr {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for ModuleName {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for ModuleName {
|
||||
fn from(string: &'a str) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<IdentStr> for ModuleName {
|
||||
fn from(string: IdentStr) -> Self {
|
||||
Self(string.as_str().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for ModuleName {
|
||||
fn from(string: Box<str>) -> Self {
|
||||
Self((string.as_ref()).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for ModuleName {
|
||||
fn from(string: String) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ModuleName> for Box<str> {
|
||||
fn from(name: ModuleName) -> Self {
|
||||
name.0.to_string().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ModuleName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ForeignSymbol {
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
pub fn as_inline_str(&self) -> &IdentStr {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for ForeignSymbol {
|
||||
fn from(string: &'a str) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<String> for ForeignSymbol {
|
||||
fn from(string: String) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Uppercase {
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
pub fn as_ident_str(&self) -> &IdentStr {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Uppercase {
|
||||
fn from(string: &'a str) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<String> for Uppercase {
|
||||
fn from(string: String) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Lowercase {
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Lowercase {
|
||||
fn from(string: &'a str) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Lowercase> for &'a str {
|
||||
fn from(lowercase: &'a Lowercase) -> Self {
|
||||
lowercase.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<String> for Lowercase {
|
||||
fn from(string: String) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for Ident {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Ident {
|
||||
fn from(string: &'a str) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for Ident {
|
||||
fn from(string: Box<str>) -> Self {
|
||||
Self((string.as_ref()).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Ident {
|
||||
fn from(string: String) -> Self {
|
||||
Self(string.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IdentStr> for Ident {
|
||||
fn from(string: IdentStr) -> Self {
|
||||
Self(string)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ident> for IdentStr {
|
||||
fn from(ident: Ident) -> Self {
|
||||
ident.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Ident> for &'a IdentStr {
|
||||
fn from(ident: &'a Ident) -> Self {
|
||||
&ident.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ident> for Box<str> {
|
||||
fn from(ident: Ident) -> Self {
|
||||
ident.0.to_string().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Ident {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Rather than displaying as this:
|
||||
///
|
||||
/// Lowercase("foo")
|
||||
///
|
||||
/// ...instead display as this:
|
||||
///
|
||||
/// 'foo'
|
||||
impl fmt::Debug for Lowercase {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "'{}'", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Lowercase {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Rather than displaying as this:
|
||||
///
|
||||
/// Uppercase("Foo")
|
||||
///
|
||||
/// ...instead display as this:
|
||||
///
|
||||
/// 'Foo'
|
||||
impl fmt::Debug for Uppercase {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "'{}'", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Uppercase {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
12
crates/compiler/module/src/lib.rs
Normal file
12
crates/compiler/module/src/lib.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
#![warn(clippy::dbg_macro)]
|
||||
// See github.com/rtfeldman/roc/issues/800 for discussion of the large_enum_variant check.
|
||||
#![allow(clippy::large_enum_variant, clippy::upper_case_acronyms)]
|
||||
|
||||
pub mod called_via;
|
||||
pub mod ident;
|
||||
pub mod low_level;
|
||||
pub mod module_err;
|
||||
pub mod symbol;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
292
crates/compiler/module/src/low_level.rs
Normal file
292
crates/compiler/module/src/low_level.rs
Normal file
|
@ -0,0 +1,292 @@
|
|||
use crate::symbol::Symbol;
|
||||
|
||||
/// Low-level operations that get translated directly into e.g. LLVM instructions.
|
||||
/// These are always wrapped when exposed to end users, and can only make it
|
||||
/// into an Expr when added directly by can::builtins
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum LowLevel {
|
||||
StrConcat,
|
||||
StrJoinWith,
|
||||
StrIsEmpty,
|
||||
StrStartsWith,
|
||||
StrStartsWithScalar,
|
||||
StrEndsWith,
|
||||
StrSplit,
|
||||
StrCountGraphemes,
|
||||
StrFromInt,
|
||||
StrFromUtf8,
|
||||
StrFromUtf8Range,
|
||||
StrToUtf8,
|
||||
StrRepeat,
|
||||
StrFromFloat,
|
||||
StrTrim,
|
||||
StrTrimLeft,
|
||||
StrTrimRight,
|
||||
StrToNum,
|
||||
StrToScalars,
|
||||
ListLen,
|
||||
ListWithCapacity,
|
||||
ListGetUnsafe,
|
||||
ListReplaceUnsafe,
|
||||
ListConcat,
|
||||
ListAppend,
|
||||
ListPrepend,
|
||||
ListMap,
|
||||
ListMap2,
|
||||
ListMap3,
|
||||
ListMap4,
|
||||
ListMapWithIndex,
|
||||
ListSortWith,
|
||||
ListSublist,
|
||||
ListDropAt,
|
||||
ListSwap,
|
||||
ListIsUnique,
|
||||
DictSize,
|
||||
DictEmpty,
|
||||
DictInsert,
|
||||
DictRemove,
|
||||
DictContains,
|
||||
DictGetUnsafe,
|
||||
DictKeys,
|
||||
DictValues,
|
||||
DictUnion,
|
||||
DictIntersection,
|
||||
DictDifference,
|
||||
DictWalk,
|
||||
SetFromList,
|
||||
SetToDict,
|
||||
NumAdd,
|
||||
NumAddWrap,
|
||||
NumAddChecked,
|
||||
NumAddSaturated,
|
||||
NumSub,
|
||||
NumSubWrap,
|
||||
NumSubChecked,
|
||||
NumSubSaturated,
|
||||
NumMul,
|
||||
NumMulWrap,
|
||||
NumMulSaturated,
|
||||
NumMulChecked,
|
||||
NumGt,
|
||||
NumGte,
|
||||
NumLt,
|
||||
NumLte,
|
||||
NumCompare,
|
||||
NumDivUnchecked,
|
||||
NumDivCeilUnchecked,
|
||||
NumRemUnchecked,
|
||||
NumIsMultipleOf,
|
||||
NumAbs,
|
||||
NumNeg,
|
||||
NumSin,
|
||||
NumCos,
|
||||
NumSqrtUnchecked,
|
||||
NumLogUnchecked,
|
||||
NumRound,
|
||||
NumToFrac,
|
||||
NumPow,
|
||||
NumCeiling,
|
||||
NumPowInt,
|
||||
NumFloor,
|
||||
NumIsFinite,
|
||||
NumAtan,
|
||||
NumAcos,
|
||||
NumAsin,
|
||||
NumBytesToU16,
|
||||
NumBytesToU32,
|
||||
NumBitwiseAnd,
|
||||
NumBitwiseXor,
|
||||
NumBitwiseOr,
|
||||
NumShiftLeftBy,
|
||||
NumShiftRightBy,
|
||||
NumShiftRightZfBy,
|
||||
NumIntCast,
|
||||
NumToFloatCast,
|
||||
NumToIntChecked,
|
||||
NumToFloatChecked,
|
||||
NumToStr,
|
||||
Eq,
|
||||
NotEq,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
Hash,
|
||||
PtrCast,
|
||||
RefCountInc,
|
||||
RefCountDec,
|
||||
BoxExpr,
|
||||
UnboxExpr,
|
||||
}
|
||||
|
||||
macro_rules! higher_order {
|
||||
() => {
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListSortWith | DictWalk
|
||||
};
|
||||
}
|
||||
|
||||
impl LowLevel {
|
||||
/// is one of the arguments always a function?
|
||||
/// An example is List.map.
|
||||
pub fn is_higher_order(&self) -> bool {
|
||||
use LowLevel::*;
|
||||
|
||||
matches!(self, higher_order!())
|
||||
}
|
||||
|
||||
pub fn function_argument_position(&self) -> usize {
|
||||
use LowLevel::*;
|
||||
|
||||
match self {
|
||||
ListMap => 1,
|
||||
ListMap2 => 2,
|
||||
ListMap3 => 3,
|
||||
ListMap4 => 4,
|
||||
ListMapWithIndex => 1,
|
||||
ListSortWith => 1,
|
||||
DictWalk => 2,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Some wrapper functions can just be replaced by lowlevels in the backend for performance.
|
||||
/// For example, Num.add should be an instruction, not a function call.
|
||||
/// Variant names are chosen to help explain what to do when adding new lowlevels
|
||||
pub enum LowLevelWrapperType {
|
||||
/// This wrapper function contains no logic and we can remove it in code gen
|
||||
CanBeReplacedBy(LowLevel),
|
||||
/// This wrapper function contains important logic and we cannot remove it in code gen
|
||||
WrapperIsRequired,
|
||||
NotALowLevelWrapper,
|
||||
}
|
||||
|
||||
impl LowLevelWrapperType {
|
||||
pub fn from_symbol(symbol: Symbol) -> LowLevelWrapperType {
|
||||
use LowLevel::*;
|
||||
use LowLevelWrapperType::*;
|
||||
|
||||
match symbol {
|
||||
Symbol::STR_CONCAT => CanBeReplacedBy(StrConcat),
|
||||
Symbol::STR_TO_SCALARS => CanBeReplacedBy(StrToScalars),
|
||||
Symbol::STR_JOIN_WITH => CanBeReplacedBy(StrJoinWith),
|
||||
Symbol::STR_IS_EMPTY => CanBeReplacedBy(StrIsEmpty),
|
||||
Symbol::STR_STARTS_WITH => CanBeReplacedBy(StrStartsWith),
|
||||
Symbol::STR_STARTS_WITH_SCALAR => CanBeReplacedBy(StrStartsWithScalar),
|
||||
Symbol::STR_ENDS_WITH => CanBeReplacedBy(StrEndsWith),
|
||||
Symbol::STR_SPLIT => CanBeReplacedBy(StrSplit),
|
||||
Symbol::STR_COUNT_GRAPHEMES => CanBeReplacedBy(StrCountGraphemes),
|
||||
Symbol::STR_FROM_UTF8 => WrapperIsRequired,
|
||||
Symbol::STR_FROM_UTF8_RANGE => WrapperIsRequired,
|
||||
Symbol::STR_TO_UTF8 => CanBeReplacedBy(StrToUtf8),
|
||||
Symbol::STR_REPEAT => CanBeReplacedBy(StrRepeat),
|
||||
Symbol::STR_TRIM => CanBeReplacedBy(StrTrim),
|
||||
Symbol::STR_TRIM_LEFT => CanBeReplacedBy(StrTrimLeft),
|
||||
Symbol::STR_TRIM_RIGHT => CanBeReplacedBy(StrTrimRight),
|
||||
Symbol::STR_TO_DEC => WrapperIsRequired,
|
||||
Symbol::STR_TO_F64 => WrapperIsRequired,
|
||||
Symbol::STR_TO_F32 => WrapperIsRequired,
|
||||
Symbol::STR_TO_NAT => WrapperIsRequired,
|
||||
Symbol::STR_TO_U128 => WrapperIsRequired,
|
||||
Symbol::STR_TO_I128 => WrapperIsRequired,
|
||||
Symbol::STR_TO_U64 => WrapperIsRequired,
|
||||
Symbol::STR_TO_I64 => WrapperIsRequired,
|
||||
Symbol::STR_TO_U32 => WrapperIsRequired,
|
||||
Symbol::STR_TO_I32 => WrapperIsRequired,
|
||||
Symbol::STR_TO_U16 => WrapperIsRequired,
|
||||
Symbol::STR_TO_I16 => WrapperIsRequired,
|
||||
Symbol::STR_TO_U8 => WrapperIsRequired,
|
||||
Symbol::STR_TO_I8 => WrapperIsRequired,
|
||||
Symbol::LIST_LEN => CanBeReplacedBy(ListLen),
|
||||
Symbol::LIST_GET => WrapperIsRequired,
|
||||
Symbol::LIST_REPLACE => WrapperIsRequired,
|
||||
Symbol::LIST_CONCAT => CanBeReplacedBy(ListConcat),
|
||||
Symbol::LIST_APPEND => CanBeReplacedBy(ListAppend),
|
||||
Symbol::LIST_PREPEND => CanBeReplacedBy(ListPrepend),
|
||||
Symbol::LIST_MAP => WrapperIsRequired,
|
||||
Symbol::LIST_MAP2 => WrapperIsRequired,
|
||||
Symbol::LIST_MAP3 => WrapperIsRequired,
|
||||
Symbol::LIST_MAP4 => WrapperIsRequired,
|
||||
Symbol::LIST_MAP_WITH_INDEX => WrapperIsRequired,
|
||||
Symbol::LIST_SORT_WITH => WrapperIsRequired,
|
||||
Symbol::LIST_SUBLIST => WrapperIsRequired,
|
||||
Symbol::LIST_DROP_AT => CanBeReplacedBy(ListDropAt),
|
||||
Symbol::LIST_SWAP => CanBeReplacedBy(ListSwap),
|
||||
Symbol::LIST_ANY => WrapperIsRequired,
|
||||
Symbol::LIST_ALL => WrapperIsRequired,
|
||||
Symbol::LIST_FIND => WrapperIsRequired,
|
||||
Symbol::DICT_LEN => CanBeReplacedBy(DictSize),
|
||||
Symbol::DICT_EMPTY => CanBeReplacedBy(DictEmpty),
|
||||
Symbol::DICT_INSERT => CanBeReplacedBy(DictInsert),
|
||||
Symbol::DICT_REMOVE => CanBeReplacedBy(DictRemove),
|
||||
Symbol::DICT_CONTAINS => CanBeReplacedBy(DictContains),
|
||||
Symbol::DICT_GET => WrapperIsRequired,
|
||||
Symbol::DICT_KEYS => CanBeReplacedBy(DictKeys),
|
||||
Symbol::DICT_VALUES => CanBeReplacedBy(DictValues),
|
||||
Symbol::DICT_UNION => CanBeReplacedBy(DictUnion),
|
||||
Symbol::DICT_INTERSECTION => CanBeReplacedBy(DictIntersection),
|
||||
Symbol::DICT_DIFFERENCE => CanBeReplacedBy(DictDifference),
|
||||
Symbol::DICT_WALK => WrapperIsRequired,
|
||||
Symbol::SET_FROM_LIST => CanBeReplacedBy(SetFromList),
|
||||
Symbol::NUM_ADD => CanBeReplacedBy(NumAdd),
|
||||
Symbol::NUM_ADD_WRAP => CanBeReplacedBy(NumAddWrap),
|
||||
Symbol::NUM_ADD_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_ADD_SATURATED => CanBeReplacedBy(NumAddSaturated),
|
||||
Symbol::NUM_SUB => CanBeReplacedBy(NumSub),
|
||||
Symbol::NUM_SUB_WRAP => CanBeReplacedBy(NumSubWrap),
|
||||
Symbol::NUM_SUB_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_SUB_SATURATED => CanBeReplacedBy(NumSubSaturated),
|
||||
Symbol::NUM_MUL => CanBeReplacedBy(NumMul),
|
||||
Symbol::NUM_MUL_WRAP => CanBeReplacedBy(NumMulWrap),
|
||||
Symbol::NUM_MUL_SATURATED => CanBeReplacedBy(NumMulSaturated),
|
||||
Symbol::NUM_MUL_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_GT => CanBeReplacedBy(NumGt),
|
||||
Symbol::NUM_GTE => CanBeReplacedBy(NumGte),
|
||||
Symbol::NUM_LT => CanBeReplacedBy(NumLt),
|
||||
Symbol::NUM_LTE => CanBeReplacedBy(NumLte),
|
||||
Symbol::NUM_COMPARE => CanBeReplacedBy(NumCompare),
|
||||
Symbol::NUM_DIV_FRAC => CanBeReplacedBy(NumDivUnchecked),
|
||||
Symbol::NUM_DIV_FRAC_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_DIV_CEIL => CanBeReplacedBy(NumDivCeilUnchecked),
|
||||
Symbol::NUM_DIV_CEIL_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_REM => CanBeReplacedBy(NumRemUnchecked),
|
||||
Symbol::NUM_REM_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_IS_MULTIPLE_OF => CanBeReplacedBy(NumIsMultipleOf),
|
||||
Symbol::NUM_ABS => CanBeReplacedBy(NumAbs),
|
||||
Symbol::NUM_NEG => CanBeReplacedBy(NumNeg),
|
||||
Symbol::NUM_SIN => CanBeReplacedBy(NumSin),
|
||||
Symbol::NUM_COS => CanBeReplacedBy(NumCos),
|
||||
Symbol::NUM_SQRT => CanBeReplacedBy(NumSqrtUnchecked),
|
||||
Symbol::NUM_SQRT_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_LOG => CanBeReplacedBy(NumLogUnchecked),
|
||||
Symbol::NUM_LOG_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_ROUND => CanBeReplacedBy(NumRound),
|
||||
Symbol::NUM_TO_FRAC => CanBeReplacedBy(NumToFrac),
|
||||
Symbol::NUM_POW => CanBeReplacedBy(NumPow),
|
||||
Symbol::NUM_CEILING => CanBeReplacedBy(NumCeiling),
|
||||
Symbol::NUM_POW_INT => CanBeReplacedBy(NumPowInt),
|
||||
Symbol::NUM_FLOOR => CanBeReplacedBy(NumFloor),
|
||||
Symbol::NUM_TO_STR => CanBeReplacedBy(NumToStr),
|
||||
// => CanBeReplacedBy(NumIsFinite),
|
||||
Symbol::NUM_ATAN => CanBeReplacedBy(NumAtan),
|
||||
Symbol::NUM_ACOS => CanBeReplacedBy(NumAcos),
|
||||
Symbol::NUM_ASIN => CanBeReplacedBy(NumAsin),
|
||||
Symbol::NUM_BYTES_TO_U16 => WrapperIsRequired,
|
||||
Symbol::NUM_BYTES_TO_U32 => WrapperIsRequired,
|
||||
Symbol::NUM_BITWISE_AND => CanBeReplacedBy(NumBitwiseAnd),
|
||||
Symbol::NUM_BITWISE_XOR => CanBeReplacedBy(NumBitwiseXor),
|
||||
Symbol::NUM_BITWISE_OR => CanBeReplacedBy(NumBitwiseOr),
|
||||
Symbol::NUM_SHIFT_LEFT => CanBeReplacedBy(NumShiftLeftBy),
|
||||
Symbol::NUM_SHIFT_RIGHT => CanBeReplacedBy(NumShiftRightBy),
|
||||
Symbol::NUM_SHIFT_RIGHT_ZERO_FILL => CanBeReplacedBy(NumShiftRightZfBy),
|
||||
Symbol::NUM_INT_CAST => CanBeReplacedBy(NumIntCast),
|
||||
Symbol::BOOL_EQ => CanBeReplacedBy(Eq),
|
||||
Symbol::BOOL_NEQ => CanBeReplacedBy(NotEq),
|
||||
Symbol::BOOL_AND => CanBeReplacedBy(And),
|
||||
Symbol::BOOL_OR => CanBeReplacedBy(Or),
|
||||
Symbol::BOOL_NOT => CanBeReplacedBy(Not),
|
||||
// => CanBeReplacedBy(Hash),
|
||||
// => CanBeReplacedBy(ExpectTrue),
|
||||
_ => NotALowLevelWrapper,
|
||||
}
|
||||
}
|
||||
}
|
30
crates/compiler/module/src/module_err.rs
Normal file
30
crates/compiler/module/src/module_err.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use snafu::{Backtrace, Snafu};
|
||||
|
||||
use crate::symbol::IdentId;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
#[snafu(visibility(pub))]
|
||||
pub enum ModuleError {
|
||||
#[snafu(display(
|
||||
"ModuleIdNotFound: I could not find the ModuleId {} in Interns.all_ident_ids: {}.",
|
||||
module_id,
|
||||
all_ident_ids
|
||||
))]
|
||||
ModuleIdNotFound {
|
||||
module_id: String,
|
||||
all_ident_ids: String,
|
||||
backtrace: Backtrace,
|
||||
},
|
||||
#[snafu(display(
|
||||
"IdentIdNotFound: I could not find IdentId {:?} in ident_ids {:?}.",
|
||||
ident_id,
|
||||
ident_ids_str
|
||||
))]
|
||||
IdentIdNotFound {
|
||||
ident_id: IdentId,
|
||||
ident_ids_str: String,
|
||||
backtrace: Backtrace,
|
||||
},
|
||||
}
|
||||
|
||||
pub type ModuleResult<T, E = ModuleError> = std::result::Result<T, E>;
|
1347
crates/compiler/module/src/symbol.rs
Normal file
1347
crates/compiler/module/src/symbol.rs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue