| /* |
| * Copyright 2015 WebAssembly Community Group participants |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <unordered_map> |
| |
| #include "parser.h" |
| |
| namespace cashew { |
| |
| // common strings |
| |
| IString TOPLEVEL("toplevel"); |
| IString DEFUN("defun"); |
| IString BLOCK("block"); |
| IString VAR("var"); |
| IString CONST("const"); |
| IString CONDITIONAL("conditional"); |
| IString BINARY("binary"); |
| IString RETURN("return"); |
| IString IF("if"); |
| IString ELSE("else"); |
| IString WHILE("while"); |
| IString DO("do"); |
| IString FOR("for"); |
| IString SEQ("seq"); |
| IString SUB("sub"); |
| IString CALL("call"); |
| IString LABEL("label"); |
| IString BREAK("break"); |
| IString CONTINUE("continue"); |
| IString SWITCH("switch"); |
| IString STRING("string"); |
| IString TRY("try"); |
| IString INF("inf"); |
| IString NaN("nan"); |
| IString LLVM_CTTZ_I32("_llvm_cttz_i32"); |
| IString UDIVMODDI4("___udivmoddi4"); |
| IString UNARY_PREFIX("unary-prefix"); |
| IString UNARY_POSTFIX("unary-postfix"); |
| IString MATH_FROUND("Math_fround"); |
| IString MATH_CLZ32("Math_clz32"); |
| IString INT64("i64"); |
| IString INT64_CONST("i64_const"); |
| IString SIMD_FLOAT32X4("SIMD_Float32x4"); |
| IString SIMD_FLOAT64X2("SIMD_Float64x2"); |
| IString SIMD_INT8X16("SIMD_Int8x16"); |
| IString SIMD_INT16X8("SIMD_Int16x8"); |
| IString SIMD_INT32X4("SIMD_Int32x4"); |
| IString PLUS("+"); |
| IString MINUS("-"); |
| IString OR("|"); |
| IString AND("&"); |
| IString XOR("^"); |
| IString L_NOT("!"); |
| IString B_NOT("~"); |
| IString LT("<"); |
| IString GE(">="); |
| IString LE("<="); |
| IString GT(">"); |
| IString EQ("=="); |
| IString NE("!="); |
| IString DIV("/"); |
| IString MOD("%"); |
| IString MUL("*"); |
| IString RSHIFT(">>"); |
| IString LSHIFT("<<"); |
| IString TRSHIFT(">>>"); |
| IString HEAP8("HEAP8"); |
| IString HEAP16("HEAP16"); |
| IString HEAP32("HEAP32"); |
| IString HEAPF32("HEAPF32"); |
| IString HEAPU8("HEAPU8"); |
| IString HEAPU16("HEAPU16"); |
| IString HEAPU32("HEAPU32"); |
| IString HEAPF64("HEAPF64"); |
| IString F0("f0"); |
| IString EMPTY(""); |
| IString FUNCTION("function"); |
| IString OPEN_PAREN("("); |
| IString OPEN_BRACE("["); |
| IString OPEN_CURLY("{"); |
| IString CLOSE_CURLY("}"); |
| IString COMMA(","); |
| IString QUESTION("?"); |
| IString COLON(":"); |
| IString CASE("case"); |
| IString DEFAULT("default"); |
| IString DOT("dot"); |
| IString PERIOD("."); |
| IString NEW("new"); |
| IString ARRAY("array"); |
| IString OBJECT("object"); |
| IString THROW("throw"); |
| IString SET("="); |
| IString ATOMICS("Atomics"); |
| IString COMPARE_EXCHANGE("compareExchange"); |
| IString LOAD("load"); |
| IString STORE("store"); |
| IString GETTER("get"); |
| IString SETTER("set"); |
| |
| IStringSet |
| keywords("var const function if else do while for break continue return " |
| "switch case default throw try catch finally true false null new"); |
| |
| const char *OPERATOR_INITS = "+-*/%<>&^|~=!,?:.", *SEPARATORS = "([;{}"; |
| |
| int MAX_OPERATOR_SIZE = 3; |
| |
| std::vector<OperatorClass> operatorClasses; |
| |
| static std::vector<std::unordered_map<IString, int>> |
| precedences; // op, type => prec |
| |
| struct Init { |
| Init() { |
| // operators, rtl, type |
| operatorClasses.emplace_back(".", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("! ~ + -", true, OperatorClass::Prefix); |
| operatorClasses.emplace_back("* / %", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("+ -", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("<< >> >>>", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("< <= > >=", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("== !=", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("&", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("^", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("|", false, OperatorClass::Binary); |
| operatorClasses.emplace_back("? :", true, OperatorClass::Tertiary); |
| operatorClasses.emplace_back("=", true, OperatorClass::Binary); |
| operatorClasses.emplace_back(",", true, OperatorClass::Binary); |
| |
| precedences.resize(OperatorClass::Tertiary + 1); |
| |
| for (size_t prec = 0; prec < operatorClasses.size(); prec++) { |
| for (auto curr : operatorClasses[prec].ops) { |
| precedences[operatorClasses[prec].type][curr] = prec; |
| } |
| } |
| } |
| }; |
| |
| Init init; |
| |
| int OperatorClass::getPrecedence(Type type, IString op) { |
| return precedences[type][op]; |
| } |
| |
| bool OperatorClass::getRtl(int prec) { return operatorClasses[prec].rtl; } |
| |
| bool isIdentInit(char x) { |
| return (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || x == '_' || |
| x == '$'; |
| } |
| bool isIdentPart(char x) { return isIdentInit(x) || (x >= '0' && x <= '9'); } |
| |
| } // namespace cashew |