Advertisement
_LINKI

GreyScript Tokenizer

Jul 14th, 2019
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.43 KB | None | 0 0
  1. if params.len < 1 then exit("Example: tokenizer [SourceCodePath]")
  2.  
  3. //Name - GSTokenParser
  4. //Author - LINKI
  5. //Version - 0.1
  6.  
  7. //
  8. // GeneralClass
  9. //
  10. GS = { }
  11.  
  12. //
  13. // TokenType
  14. //
  15. GS.TokenType = { }
  16. GS.TokenType.add = function(type)
  17.     self[type] = self.index //NUM = 0
  18.     self[self.index] = type //0 = NUM
  19.     self.index = self.index + 1
  20. end function
  21. GS.TokenType.ctor = function()
  22.     self.index = 0
  23.     //Basic
  24.     self.add("NUM")     //  123... 9.9
  25.     self.add("STR")     //  "String"
  26.     self.add("WORD")        //  var, func
  27.    
  28.     self.add("TRUE")        //  true
  29.     self.add("FALSE")       //  false
  30.     self.add("NULL")        //  null
  31.     //Statements
  32.     self.add("IF")      //  if
  33.     self.add("THEN")        //  then
  34.     self.add("ELSE")        //  else
  35.     self.add("WHILE")       //  while
  36.     self.add("FOR")     //  for
  37.     self.add("IN")      //  in
  38.     self.add("FUNC")        //  function
  39.     self.add("SELF")        //  self
  40.     self.add("END")     //  end
  41.     self.add("RET")     //  return
  42.    
  43.     self.add("REF")     //  @
  44.     //Math
  45.     self.add("ADD")     //  +
  46.     self.add("SUB")     //  -
  47.     self.add("MUL")     //  *
  48.     self.add("DIV")     //  /
  49.     self.add("PNT")     //  %
  50.     self.add("CRT")     //  ^
  51.     //Logic
  52.     self.add("NOT")     //  !/not
  53.     self.add("AND")     //  &&/and
  54.     self.add("OR")      //  ||/or
  55.     self.add("EQ")      //  =
  56.     self.add("LESS")        //  <
  57.     self.add("GRT")     //  >
  58.     self.add("NOTEQ")       //  !=
  59.     self.add("EQEQ")        //  ==
  60.     self.add("LESSEQ")  //  <=
  61.     self.add("GRTEQ")       //  >=
  62.     //BlockSymbols
  63.     self.add("LPNT")        //  (
  64.     self.add("RPNT")        //  )
  65.     self.add("LBKT")        //  [
  66.     self.add("RBKT")        //  ]
  67.     self.add("LBRC")        //  {
  68.     self.add("RBRC")        //  }
  69.     //Symbols
  70.     self.add("SEMI")        //  ;
  71.     self.add("COLON")       //  :
  72.     self.add("COMMA")       //  ,
  73.     self.add("DOT")     // .
  74.    
  75.     self.add("EOF")     //  \0
  76.    
  77.     self.remove("index")
  78.     self.remove("ctor")
  79. end function
  80. GS.TokenType.ctor()//Initialize
  81.  
  82. //
  83. // Token
  84. //
  85. GS.Token = { }
  86. GS.Token.ctor = function(type, value = null)
  87.     self.type = type
  88.     if value != null then self.value = value
  89.     self.remove("ctor")
  90. end function
  91. GS.Token.create = function(type, value = null)
  92.     t = new self
  93.     t.ctor(type, value)
  94.     t.remove("__isa")
  95.     return t
  96. end function
  97. GS.Token.hasValue = function(token)
  98.     return token.hasIndex("value")
  99. end function
  100. GS.Token.toString = function(token)
  101.     buff = GS.TokenType[token.type]
  102.     if self.hasValue(token) then buff = buff + ":" + token.value
  103.     return buff
  104. end function
  105.  
  106. //
  107. // StatementsTable
  108. //
  109. GS.StatementsTable = { }
  110. GS.StatementsTable.ctor = function()
  111.     self["if"] = GS.TokenType.IF
  112.     self["then"] = GS.TokenType.THEN
  113.     self["else"] = GS.TokenType.ELSE
  114.     self["while"] = GS.TokenType.WHILE
  115.     self["for"] = GS.TokenType.FOR
  116.     self["in"] = GS.TokenType.IN
  117.     self["function"] = GS.TokenType.FUNC
  118.     self["self"] = GS.TokenType.SELF
  119.     self["end"] = GS.TokenType.END
  120.     self["return"] = GS.TokenType.RET
  121.    
  122.     self["not"] = GS.TokenType.NOT
  123.     self["and"] = GS.TokenType.AND
  124.     self["or"] = GS.TokenType.OR
  125.    
  126.     self["true"] = GS.TokenType.TRUE
  127.     self["false"] = GS.TokenType.FALSE
  128.     self["null"] = GS.TokenType.NULL
  129.    
  130.     self.remove("ctor")
  131. end function
  132. GS.StatementsTable.ctor()//Initialize
  133.  
  134. //
  135. // SymbolsTable
  136. //
  137. GS.SymbolsTable = { }
  138. GS.SymbolsTable.ctor = function()
  139.     self["+"] = GS.TokenType.ADD
  140.     self["-"] = GS.TokenType.SUB
  141.     self["*"] = GS.TokenType.MUL
  142.     self["/"] = GS.TokenType.DIV
  143.     self["%"] = GS.TokenType.PNT
  144.     self["^"] = GS.TokenType.CRT
  145.    
  146.     self["@"] = GS.TokenType.REF
  147.     self["!"] = GS.TokenType.NOT
  148.     self["&&"] = GS.TokenType.AND
  149.     self["||"] = GS.TokenType.OR
  150.     self["="] = GS.TokenType.EQ
  151.     self["<"] = GS.TokenType.LESS
  152.     self[">"] = GS.TokenType.GRT
  153.     self["!="] = GS.TokenType.NOTEQ
  154.     self["=="] = GS.TokenType.EQEQ
  155.     self["<="] = GS.TokenType.LESSEQ
  156.     self[">="] = GS.TokenType.GRTEQ
  157.    
  158.     self["("] = GS.TokenType.LPNT
  159.     self[")"] = GS.TokenType.RPNT
  160.     self["["] = GS.TokenType.LBKT
  161.     self["]"] = GS.TokenType.RBKT
  162.     self["{"] = GS.TokenType.LBRC
  163.     self["}"] = GS.TokenType.RBRC
  164.     self[";"] = GS.TokenType.SEMI
  165.     self[":"] = GS.TokenType.COLON
  166.     self[","] = GS.TokenType.COMMA
  167.     self["."] = GS.TokenType.DOT
  168.    
  169.     self.remove("ctor")
  170. end function
  171. GS.SymbolsTable.ctor()//Initialize
  172.  
  173. //
  174. // TokenParser
  175. //
  176. GS.TokenParser = { }
  177.  
  178. GS.TokenParser.NONE = ""
  179. GS.TokenParser.SPACE = " "
  180. GS.TokenParser.USCORE = "_"
  181. GS.TokenParser.DOT = "."
  182. GS.TokenParser.COMMENT = "//"
  183. GS.TokenParser.QUOTE = """"
  184. GS.TokenParser.NLINE = char(10)
  185. GS.TokenParser.TAB = char(9)
  186. GS.TokenParser.EOF = char(0)
  187.  
  188. GS.TokenParser.nums = "1234567890"
  189. GS.TokenParser.letters = "abcdefghijklmnopqrstuvwxyz"
  190. GS.TokenParser.parse = function(code)
  191.     self.curr = 0
  192.     self.code = code
  193.     tokens = []
  194.     while self.curr < self.code.len
  195.         ch1 = self.peek(0)
  196.         ch2 = self.peek(1)
  197.         ch12 = ch1 + ch2
  198.         if self.isNumber(ch1) then
  199.             tokens.push(self.parseNumber())
  200.         else if self.isLetter(ch1) or ch1 == self.USCORE then
  201.             tokens.push(self.parseWord())
  202.         else if ch1 == self.QUOTE then
  203.             tokens.push(self.parseString())
  204.         else if ch12 == self.COMMENT then
  205.             self.parseCommentLine()
  206.         else if GS.SymbolsTable.hasIndex(ch12) then
  207.             self.AddCurr(2)
  208.             tokens.push(GS.Token.create(GS.SymbolsTable[ch12]))
  209.         else if GS.SymbolsTable.hasIndex(ch1) then
  210.             self.AddCurr()
  211.             tokens.push(GS.Token.create(GS.SymbolsTable[ch1]))
  212.         else if self.isWhitespace(ch1) or self.isNewLine(ch1) or self.isEOF(ch1) then
  213.             self.AddCurr()
  214.         end if
  215.     end while
  216.    
  217.     return tokens
  218. end function
  219.  
  220. //
  221. // ParseFunctions
  222. //
  223. GS.TokenParser.parseNumber = function()
  224.     buff = self.get()
  225.     doubled = false
  226.    
  227.     while true
  228.         ch = self.peek()
  229.         if not self.isNumber(ch) then
  230.             if ch == self.DOT and not doubled then
  231.                 doubled = true
  232.             else
  233.                 break
  234.             end if
  235.         end if
  236.         buff = buff + ch
  237.         self.AddCurr()
  238.     end while
  239.    
  240.     return GS.Token.create(GS.TokenType.NUM, buff.to_int)
  241. end function
  242. GS.TokenParser.parseString = function()
  243.     self.AddCurr(1) //"
  244.     buff = self.NONE
  245.    
  246.     while true
  247.         ch = self.get()
  248.         chNext = self.peek()
  249.        
  250.         if ch == self.QUOTE and chNext != self.QUOTE then break
  251.         if ch == self.QUOTE and chNext == self.QUOTE then self.AddCurr()
  252.         if self.isNewLine(ch) or self.isEOF(ch) then exit("Expected - '""'")
  253.        
  254.         buff = buff + ch
  255.     end while
  256.    
  257.     return GS.Token.create(GS.TokenType.STR, buff)
  258. end function
  259. GS.TokenParser.parseWord = function()
  260.     buff = self.get()
  261.    
  262.     while true
  263.         ch = self.peek()
  264.         if not self.isLetterOrNumber(ch) and not ch == self.USCORE then break
  265.        
  266.         buff = buff + ch
  267.         self.AddCurr()
  268.     end while
  269.    
  270.     if GS.StatementsTable.hasIndex(buff) then return GS.Token.create(GS.StatementsTable[buff])
  271.     return GS.Token.create(GS.TokenType.WORD, buff)
  272. end function
  273. GS.TokenParser.parseCommentLine = function()
  274.     self.AddCurr(2)
  275.     while true
  276.         ch = self.get()
  277.         if self.isNewLine(ch) or self.isEOF(ch) then break
  278.     end while
  279. end function
  280.  
  281. //
  282. // CharFunctions
  283. //
  284. GS.TokenParser.isWhitespace = function(ch)
  285.     return ch == self.SPACE or self.TAB or not ch
  286. end function
  287. GS.TokenParser.isEOF = function(ch)
  288.     return ch == self.EOF
  289. end function
  290. GS.TokenParser.isNewLine = function(ch)
  291.     return ch == self.NLINE
  292. end function
  293. GS.TokenParser.isLetterOrNumber = function(ch)
  294.     return self.isLetter(ch) or self.isNumber(ch)
  295. end function
  296. GS.TokenParser.isLetter = function(ch)
  297.     if self.letters.indexOf(ch.lower()) == null then return false
  298.     return true
  299. end function
  300. GS.TokenParser.isNumber = function(ch)
  301.     if self.nums.indexOf(ch) == null then return false
  302.     return true
  303. end function
  304.  
  305. //
  306. // ParseUtils
  307. //
  308. GS.TokenParser.get = function(s = 0)
  309.     ch = self.peek(s)
  310.     self.AddCurr()
  311.     return ch
  312. end function
  313. GS.TokenParser.peek = function(s = 0)
  314.     i = self.curr + s
  315.     if not self.isRange(i) then return self.EOF
  316.     return self.code[i]
  317. end function
  318. GS.TokenParser.isRange = function(i)
  319.     if i >= self.code.len then return false
  320.     return true
  321. end function
  322. GS.TokenParser.AddCurr = function(i = 1)
  323.     self.curr = self.curr + i
  324. end function
  325.  
  326. pc = get_shell().host_computer
  327. inputFilePath = params[0]
  328. inputFile = pc.File(inputFilePath)
  329. code = inputFile.content
  330.  
  331. print("Parsing...")
  332. st = time()
  333. tokens = GS.TokenParser.parse(code)
  334. et = time()
  335. print("EndParse")
  336. print("CountTokens: " + tokens.len)
  337. print("ElapsedTime: " + (et - st))
  338.  
  339. outFolder = parent_path(inputFile.path)
  340. outName = inputFile.name + "_tokens.txt"
  341. outPath = outFolder + "/" + outName
  342.  
  343. outFile = pc.File(outPath)
  344. if not outFile then
  345.     pc.touch(outFolder, outName)
  346.     outFile = pc.File(outPath)
  347. end if
  348. if not outFile then exit("Out file error :/")
  349.  
  350. content = ""
  351. for token in tokens
  352.     content = content + GS.Token.toString(token) + "\n"
  353. end for
  354.  
  355. outFile.set_content(content)
  356. print("Tokens saved to - '" + outFile.path + "'")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement