summary refs log blame commit diff stats
path: root/rod/wordrecg.nim
blob: c460d019e90fab8878461de9a849b103accd50b1 (plain) (tree)

















































































































































                                                                                                              
#
#
#           The Nimrod Compiler
#        (c) Copyright 2009 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# This module contains a word recognizer, i.e. a simple
# procedure which maps special words to an enumeration.
# It is primarily needed because Pascal's case statement
# does not support strings. Without this the code would
# be slow and unreadable.

import 
  nhashes, strutils, idents

type 
  TSpecialWord* = enum 
    wInvalid, # these are mapped to Nimrod keywords:
              #[[[cog
              #from string import split, capitalize
              #keywords = split(open("data/keywords.txt").read())
              #idents = ""
              #strings = ""
              #i = 1
              #for k in keywords:
              #  idents = idents + "w" + capitalize(k) + ", "
              #  strings = strings + "'" + k + "', "
              #  if i % 4 == 0:
              #    idents = idents + "\n"
              #    strings = strings + "\n"
              #  i = i + 1
              #cog.out(idents)
              #]]]
    wAddr, wAnd, wAs, wAsm, wBind, wBlock, wBreak, wCase, wCast, wConst, 
    wContinue, wConverter, wDiscard, wDistinct, wDiv, wElif, wElse, wEnd, wEnum, 
    wExcept, wFinally, wFor, wFrom, wGeneric, wIf, wImplies, wImport, wIn, 
    wInclude, wIs, wIsnot, wIterator, wLambda, wMacro, wMethod, wMod, wNil, 
    wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, 
    wShl, wShr, wTemplate, wTry, wTuple, wType, wVar, wWhen, wWhile, wWith, 
    wWithout, wXor, wYield,   #[[[end]]]
                              # other special tokens:
    wColon, wEquals, wDot, wDotDot, wHat, wStar, wMinus, # pragmas and command line options:
    wMagic, wTypeCheck, wFinal, wProfiler, wObjChecks, wImportc, wExportc, 
    wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader, 
    wNosideeffect, wNoreturn, wMerge, wLib, wDynlib, wCompilerproc, wProcVar, 
    wFatal, wError, wWarning, wHint, wLine, wPush, wPop, wDefine, wUndef, 
    wLinedir, wStacktrace, wLinetrace, wParallelBuild, wLink, wCompile, 
    wLinksys, wDeprecated, wVarargs, wByref, wCallconv, wBreakpoint, wDebugger, 
    wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline, 
    wFastcall, wClosure, wNoconv, wOn, wOff, wChecks, wRangechecks, 
    wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wW, 
    wHints, wOptimization, wSpeed, wSize, wNone, wPath, wP, wD, wU, wDebuginfo, 
    wCompileonly, wNolinking, wForcebuild, wF, wDeadCodeElim, wSafecode, 
    wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui, 
    wPassc, wT, wPassl, wL, wListcmd, wGendoc, wGenmapping, wOs, wCpu, 
    wGenerate, wG, wC, wCpp, wBorrow, wRun, wR, wVerbosity, wV, wHelp, wH, 
    wSymbolFiles, wFieldChecks, wX, wVersion, wAdvanced, wSkipcfg, wSkipProjCfg, 
    wCc, wGenscript, wCheckPoint, wCheckPoints, wNoMain, wSubsChar, wAcyclic, wIndex, # 
                                                                                      # commands:
    wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty, 
    wDoc, wPas, wGenDepend, wListDef, wCheck, wParse, wScan, wBoot, wLazy, 
    wRst2html, wRst2tex, wI,  # special for the preprocessor of configuration files:
    wWrite, wPutEnv, wPrependEnv, wAppendEnv, # additional Pascal keywords:
    wArray, wBegin, wClass, wConstructor, wDestructor, wDo, wDownto, wExports, 
    wFinalization, wFunction, wGoto, wImplementation, wInherited, 
    wInitialization, wInterface, wLabel, wLibrary, wPacked, wProcedure, 
    wProgram, wProperty, wRecord, wRepeat, wResourcestring, wSet, wThen, 
    wThreadvar, wTo, wUnit, wUntil, wUses, # Pascal special tokens:
    wExternal, wOverload, wFar, wAssembler, wForward, wIfdef, wIfndef, wEndif
  TSpecialWords* = set[TSpecialWord]

const 
  oprLow* = ord(wColon)
  oprHigh* = ord(wHat)
  specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["", # 
                                                                             # keywords:
                                                                             #
                                                                             #[[[cog
                                                                             #
                                                                             #cog.out(strings)
                                                                             #]]]
    "addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", 
    "const", "continue", "converter", "discard", "distinct", "div", "elif", 
    "else", "end", "enum", "except", "finally", "for", "from", "generic", "if", 
    "implies", "import", "in", "include", "is", "isnot", "iterator", "lambda", 
    "macro", "method", "mod", "nil", "not", "notin", "object", "of", "or", 
    "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template", 
    "try", "tuple", "type", "var", "when", "while", "with", "without", "xor", "yield", #[[[end]]]
                                                                                       # other special tokens:
    ":", "=", ".", "..", "^", "*", "-", # pragmas and command line options:
    "magic", "typecheck", "final", "profiler", "objchecks", "importc", 
    "exportc", "align", "nodecl", "pure", "volatile", "register", "sideeffect", 
    "header", "nosideeffect", "noreturn", "merge", "lib", "dynlib", 
    "compilerproc", "procvar", "fatal", "error", "warning", "hint", "line", 
    "push", "pop", "define", "undef", "linedir", "stacktrace", "linetrace", 
    "parallelbuild", "link", "compile", "linksys", "deprecated", "varargs", 
    "byref", "callconv", "breakpoint", "debugger", "nimcall", "stdcall", 
    "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "closure", 
    "noconv", "on", "off", "checks", "rangechecks", "boundchecks", 
    "overflowchecks", "nilchecks", "assertions", "warnings", "w", "hints", 
    "optimization", "speed", "size", "none", "path", "p", "d", "u", "debuginfo", 
    "compileonly", "nolinking", "forcebuild", "f", "deadcodeelim", "safecode", 
    "compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console", 
    "gui", "passc", "t", "passl", "l", "listcmd", "gendoc", "genmapping", "os", 
    "cpu", "generate", "g", "c", "cpp", "borrow", "run", "r", "verbosity", "v", 
    "help", "h", "symbolfiles", "fieldchecks", "x", "version", "advanced", 
    "skipcfg", "skipprojcfg", "cc", "genscript", "checkpoint", "checkpoints", 
    "nomain", "subschar", "acyclic", "index", # commands:
    "compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm", 
    "pretty", "doc", "pas", "gendepend", "listdef", "check", "parse", "scan", 
    "boot", "lazy", "rst2html", "rst2tex", "i", # special for the preprocessor of configuration files:
    "write", "putenv", "prependenv", "appendenv", "array", "begin", "class", 
    "constructor", "destructor", "do", "downto", "exports", "finalization", 
    "function", "goto", "implementation", "inherited", "initialization", 
    "interface", "label", "library", "packed", "procedure", "program", 
    "property", "record", "repeat", "resourcestring", "set", "then", 
    "threadvar", "to", "unit", "until", "uses", # Pascal special tokens
    "external", "overload", "far", "assembler", "forward", "ifdef", "ifndef", 
    "endif"]

proc whichKeyword*(id: PIdent): TSpecialWord
proc whichKeyword*(id: String): TSpecialWord
proc findStr*(a: openarray[string], s: string): int
# implementation

proc findStr(a: openarray[string], s: string): int = 
  for i in countup(low(a), high(a)): 
    if cmpIgnoreStyle(a[i], s) == 0: 
      return i
  result = - 1

proc whichKeyword(id: String): TSpecialWord = 
  result = whichKeyword(getIdent(id))

proc whichKeyword(id: PIdent): TSpecialWord = 
  if id.id < 0: result = wInvalid
  else: result = TSpecialWord(id.id)
  
proc initSpecials() = 
  # initialize the keywords:
  for s in countup(succ(low(specialWords)), high(specialWords)): 
    getIdent(specialWords[s], getNormalizedHash(specialWords[s])).id = ord(s)
  
initSpecials()