// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // Symbol.go package expr import ( "strings" ) var symbolMap map[Symbol]symbolSpec type symbolClass int16 const ( symClassOperator symbolClass = iota symClassPostOp symClassIdentifier symClassDelimiter 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: {"'", symClassDelimiter}, // 20: '\'' SymDoubleQuote: {"\"", symClassDelimiter}, // 21: '"' SymBackTick: {"`", symClassOperator}, // 22: '`' SymExclamation: {"!", symClassPostOp}, // 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: '::' SymDoubleGreater: {">>", symClassOperator}, // 52: '>>' SymDoubleLess: {"<<", symClassOperator}, // 53: '<<' SymCaret: {"^", symClassOperator}, // 54: '^' SymDollarRound: {"$(", symClassOperator}, // 55: '$(' SymOpenClosedRound: {"()", symClassPostOp}, // 56: '()' SymDoubleDollar: {"$$", symClassOperator}, // 57: '$$' SymDoubleDot: {"..", symClassOperator}, // 58: '..' SymTripleDot: {"...", symClassOperator}, // 59: '...' SymStarEqual: {"*=", symClassOperator}, // 60: '*=' SymSlashEqual: {"/=", symClassOperator}, // 61: '/=' SymPercEqual: {"%=", symClassOperator}, // 62: '%=' SymPlusGreater: {"+>", symClassOperator}, // 63: '+>' SymLessPlus: {"<+", symClassOperator}, // 64: '<+' // 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 if len(symList) == 0 { sb.WriteString("") } else { for _, sym := range symList { if sb.Len() > 0 { sb.WriteByte(',') 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 }