diff --git a/symbol-map.go b/symbol-map.go new file mode 100644 index 0000000..7b23740 --- /dev/null +++ b/symbol-map.go @@ -0,0 +1,174 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// Symbol.go +package expr + +import ( + "strings" +) + +var symbolMap map[Symbol]symbolSpec + +const operatorBaseSymbol = SymMinus + +type symbolClass int16 + +const ( + symClassOperator symbolClass = (1 << iota) + symClassIdentifier + symClassParenthesis + symClassDeclaration + symClassValue + symClassOther +) + +type symbolSpec struct { + repr string + kind symbolClass +} + +func init() { + + symbolMap = map[Symbol]symbolSpec{ + SymUnknown: {"", symClassOther}, // -1: Unknown symbol + SymNone: {"", symClassOther}, // 0: Null value for variable of type symbol + SymError: {"", symClassOther}, // 1: Error reading from stream + SymEos: {"", symClassOther}, // 2: End of stream + SymMinus: {"-", symClassOperator}, // 3: '-' + SymMinusEqual: {"-=", symClassOperator}, // 4: '-=' + SymDoubleMinus: {"--", symClassOperator}, // 5: '--' + SymPlus: {"+", symClassOperator}, // 6: '+' + SymPlusEqual: {"+=", symClassOperator}, // 7: '+=' + SymDoublePlus: {"++", symClassOperator}, // 8: '++' + SymStar: {"*", symClassOperator}, // 9: '*' + SymDoubleStar: {"**", symClassOperator}, // 10: '**' + SymSlash: {"/", symClassOperator}, // 11: '/' + SymBackSlash: {"\\", symClassOperator}, // 12: '\' + SymVertBar: {"|", symClassOperator}, // 13: '|' + SymDoubleVertBar: {"||", symClassOperator}, // 14: '||' + SymComma: {",", symClassOperator}, // 15: ',' + SymColon: {":", symClassOperator}, // 16: ':' + SymSemiColon: {";", symClassOperator}, // 17: ';' + SymDot: {".", symClassOperator}, // 18: '.' + SymDotSlash: {"./", symClassOperator}, // 19: './' + SymQuote: {"'", symClassOperator}, // 20: '\'' + SymDoubleQuote: {"\"", symClassOperator}, // 21: '"' + SymBackTick: {"`", symClassOperator}, // 22: '`' + SymExclamation: {"!", symClassOperator}, // 23: '!' + SymQuestion: {"?", symClassOperator}, // 24: '?' + SymAmpersand: {"&", symClassOperator}, // 25: '&' + SymDoubleAmpersand: {"&&", symClassOperator}, // 26: '&&' + SymPercent: {"%", symClassOperator}, // 27: '%' + SymAt: {"@", symClassOperator}, // 28: '@' + SymUndescore: {"_", symClassOperator}, // 29: '_' + SymEqual: {"=", symClassOperator}, // 30: '=' + SymDoubleEqual: {"==", symClassOperator}, // 31: '==' + SymLess: {"<", symClassOperator}, // 32: '<' + SymLessOrEqual: {"<=", symClassOperator}, // 33: '<=' + SymGreater: {">", symClassOperator}, // 34: '>' + SymGreaterOrEqual: {">=", symClassOperator}, // 35: '>=' + SymLessGreater: {"<>", symClassOperator}, // 36: '<>' + SymNotEqual: {"!=", symClassOperator}, // 37: '!=' + SymDollar: {"$", symClassOperator}, // 38: '$' + SymHash: {"#", symClassOperator}, // 39: '#' + SymOpenRound: {"(", symClassParenthesis}, // 40: '(' + SymClosedRound: {")", symClassParenthesis}, // 41: ')' + SymOpenSquare: {"[", symClassParenthesis}, // 42: '[' + SymClosedSquare: {"]", symClassParenthesis}, // 43: ']' + SymOpenBrace: {"{", symClassParenthesis}, // 44: '{' + SymClosedBrace: {"}", symClassParenthesis}, // 45: '}' + SymTilde: {"~", symClassOperator}, // 46: '~' + SymDoubleQuestion: {"??", symClassOperator}, // 47: '??' + SymQuestionEqual: {"?=", symClassOperator}, // 48: '?=' + SymQuestionExclam: {"?!", symClassOperator}, // 49: '?!' + SymDoubleAt: {"@@", symClassOperator}, // 50: '@@' + SymDoubleColon: {"::", symClassOperator}, // 51: '::' + SymInsert: {">>", symClassOperator}, // 52: '>>' + SymAppend: {"<<", symClassOperator}, // 53: '<<' + SymCaret: {"^", symClassOperator}, // 54: '^' + SymDollarRound: {"$(", symClassOperator}, // 55: '$(' + SymOpenClosedRound: {"()", symClassOperator}, // 56: '()' + SymDoubleDollar: {"$$", symClassOperator}, // 57: '$$' + SymDoubleDot: {"..", symClassOperator}, // 58: '..' + SymTripleDot: {"...", symClassOperator}, // 59: '...' + SymStarEqual: {"*=", symClassOperator}, // 60: '*=' + // SymChangeSign + // SymUnchangeSign + // SymIdentifier + // SymBool + // SymInteger + // SymVariable + // SymFloat + // SymFraction + // SymString + // SymIterator + // SymOr: "or", + // SymAnd: "and", + // SymNot: "not", + // SymComment + // SymFuncCall + // SymFuncDef + // SymList + // SymDict + // SymIndex + // SymExpression + // SymSelector // ::= "?" {":" } ["::" ] + // SymSelectorCase // ::= [] "{" "}" + // // SymOpenComment // 0: '/*' + // // SymClosedComment // 0: '*/' + // // SymOneLineComment // 0: '//' + // keywordBase + SymKwAnd: {"and", symClassOperator}, + SymKwNot: {"not", symClassOperator}, + SymKwOr: {"or", symClassOperator}, + SymKwBut: {"but", symClassOperator}, + SymKwFunc: {"func(", symClassDeclaration}, + SymKwBuiltin: {"builtin", symClassOperator}, + SymKwPlugin: {"plugin", symClassOperator}, + SymKwIn: {"in", symClassOperator}, + SymKwInclude: {"include", symClassOperator}, + SymKwNil: {"nil", symClassValue}, + SymKwUnset: {"unset", symClassOperator}, + } +} + +func SymToString(sym Symbol) string { + if s, ok := symbolMap[sym]; ok { + return s.repr + } + return "" +} + +func SymListToString(symList []Symbol, quote bool) string { + var sb strings.Builder + for _, sym := range symList { + if sb.Len() > 0 { + sb.WriteByte(',') + } + if quote { + sb.WriteByte('\'') + } + sb.WriteString(SymToString(sym)) + if quote { + sb.WriteByte('\'') + } + } + return sb.String() +} + +func StringEndsWithOperator(s string) bool { + return endingOperator(s) != SymNone +} + +func endingOperator(s string) (sym Symbol) { + sym = SymNone + lower := strings.ToLower(s) + for symbol, spec := range symbolMap { + if spec.kind == symClassOperator && strings.HasSuffix(lower, spec.repr) { + sym = symbol + break + } + } + return +}