Advertisement
Guest User

Untitled

a guest
Feb 24th, 2020
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 64.25 KB | None | 0 0
  1. #######################################
  2. # IMPORTS
  3. #######################################
  4.  
  5. from strings_with_arrows import *
  6.  
  7. import string
  8. import os
  9. import math
  10.  
  11. #######################################
  12. # CONSTANTS
  13. #######################################
  14.  
  15. DIGITS = '0123456789'
  16. LETTERS = string.ascii_letters
  17. LETTERS_DIGITS = LETTERS + DIGITS
  18.  
  19. #######################################
  20. # ERRORS
  21. #######################################
  22.  
  23. class Error:
  24.   def __init__(self, pos_start, pos_end, error_name, details):
  25.     self.pos_start = pos_start
  26.     self.pos_end = pos_end
  27.     self.error_name = error_name
  28.     self.details = details
  29.  
  30.   def as_string(self):
  31.     result  = f'{self.error_name}: {self.details}\n'
  32.     result += f'File {self.pos_start.fn}, line {self.pos_start.ln + 1}'
  33.     result += '\n\n' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
  34.     return result
  35.  
  36. class IllegalCharError(Error):
  37.   def __init__(self, pos_start, pos_end, details):
  38.     super().__init__(pos_start, pos_end, 'Illegal Character', details)
  39.  
  40. class ExpectedCharError(Error):
  41.   def __init__(self, pos_start, pos_end, details):
  42.     super().__init__(pos_start, pos_end, 'Expected Character', details)
  43.  
  44. class InvalidSyntaxError(Error):
  45.   def __init__(self, pos_start, pos_end, details=''):
  46.     super().__init__(pos_start, pos_end, 'Invalid Syntax', details)
  47.  
  48. class RTError(Error):
  49.   def __init__(self, pos_start, pos_end, details, context):
  50.     super().__init__(pos_start, pos_end, 'Runtime Error', details)
  51.     self.context = context
  52.  
  53.   def as_string(self):
  54.     result  = self.generate_traceback()
  55.     result += f'{self.error_name}: {self.details}'
  56.     result += '\n\n' + string_with_arrows(self.pos_start.ftxt, self.pos_start, self.pos_end)
  57.     return result
  58.  
  59.   def generate_traceback(self):
  60.     result = ''
  61.     pos = self.pos_start
  62.     ctx = self.context
  63.  
  64.     while ctx:
  65.       result = f'  File {pos.fn}, line {str(pos.ln + 1)}, in {ctx.display_name}\n' + result
  66.       pos = ctx.parent_entry_pos
  67.       ctx = ctx.parent
  68.  
  69.     return 'Traceback (most recent call last):\n' + result
  70.  
  71. #######################################
  72. # POSITION
  73. #######################################
  74.  
  75. class Position:
  76.   def __init__(self, idx, ln, col, fn, ftxt):
  77.     self.idx = idx
  78.     self.ln = ln
  79.     self.col = col
  80.     self.fn = fn
  81.     self.ftxt = ftxt
  82.  
  83.   def advance(self, current_char=None):
  84.     self.idx += 1
  85.     self.col += 1
  86.  
  87.     if current_char == '\n':
  88.       self.ln += 1
  89.       self.col = 0
  90.  
  91.     return self
  92.  
  93.   def copy(self):
  94.     return Position(self.idx, self.ln, self.col, self.fn, self.ftxt)
  95.  
  96. #######################################
  97. # TOKENS
  98. #######################################
  99.  
  100. TT_INT              = 'INT'
  101. TT_FLOAT        = 'FLOAT'
  102. TT_STRING           = 'STRING'
  103. TT_IDENTIFIER   = 'IDENTIFIER'
  104. TT_KEYWORD      = 'KEYWORD'
  105. TT_PLUS         = 'PLUS'
  106. TT_MINUS        = 'MINUS'
  107. TT_MUL          = 'MUL'
  108. TT_DIV          = 'DIV'
  109. TT_POW              = 'POW'
  110. TT_EQ                   = 'EQ'
  111. TT_LPAREN       = 'LPAREN'
  112. TT_RPAREN       = 'RPAREN'
  113. TT_LSQUARE    = 'LSQUARE'
  114. TT_RSQUARE    = 'RSQUARE'
  115. TT_EE                   = 'EE'
  116. TT_NE                   = 'NE'
  117. TT_LT                   = 'LT'
  118. TT_GT                   = 'GT'
  119. TT_LTE              = 'LTE'
  120. TT_GTE              = 'GTE'
  121. TT_COMMA            = 'COMMA'
  122. TT_ARROW            = 'ARROW'
  123. TT_NEWLINE      = 'NEWLINE'
  124. TT_EOF              = 'EOF'
  125.  
  126. KEYWORDS = [
  127.   'var',
  128.   'and',
  129.   'or',
  130.   'not',
  131.   'if',
  132.   'otherif',
  133.   'otherwise',
  134.   'for',
  135.   'to',
  136.   'step',
  137.   'while',
  138.   'func',
  139.   'then',
  140.   'end',
  141.   'return',
  142.   'continue',
  143.   'break',
  144. ]
  145.  
  146. class Token:
  147.   def __init__(self, type_, value=None, pos_start=None, pos_end=None):
  148.     self.type = type_
  149.     self.value = value
  150.  
  151.     if pos_start:
  152.       self.pos_start = pos_start.copy()
  153.       self.pos_end = pos_start.copy()
  154.       self.pos_end.advance()
  155.  
  156.     if pos_end:
  157.       self.pos_end = pos_end.copy()
  158.  
  159.   def matches(self, type_, value):
  160.     return self.type == type_ and self.value == value
  161.  
  162.   def __repr__(self):
  163.     if self.value: return f'{self.type}:{self.value}'
  164.     return f'{self.type}'
  165.  
  166. #######################################
  167. # LEXER
  168. #######################################
  169.  
  170. class Lexer:
  171.   def __init__(self, fn, text):
  172.     self.fn = fn
  173.     self.text = text
  174.     self.pos = Position(-1, 0, -1, fn, text)
  175.     self.current_char = None
  176.     self.advance()
  177.  
  178.   def advance(self):
  179.     self.pos.advance(self.current_char)
  180.     self.current_char = self.text[self.pos.idx] if self.pos.idx < len(self.text) else None
  181.  
  182.   def make_tokens(self):
  183.     tokens = []
  184.  
  185.     while self.current_char != None:
  186.       if self.current_char in ' \t':
  187.         self.advance()
  188.       elif self.current_char == '#':
  189.         self.skip_comment()
  190.       elif self.current_char in ' \n':
  191.         tokens.append(Token(TT_NEWLINE, pos_start=self.pos))
  192.         self.advance()
  193.       elif self.current_char in DIGITS:
  194.         tokens.append(self.make_number())
  195.       elif self.current_char in LETTERS:
  196.         tokens.append(self.make_identifier())
  197.       elif self.current_char == '"':
  198.         tokens.append(self.make_string())
  199.       elif self.current_char == '+':
  200.         tokens.append(Token(TT_PLUS, pos_start=self.pos))
  201.         self.advance()
  202.       elif self.current_char == '-':
  203.         tokens.append(self.make_minus_or_arrow())
  204.       elif self.current_char == '*':
  205.         tokens.append(Token(TT_MUL, pos_start=self.pos))
  206.         self.advance()
  207.       elif self.current_char == '/':
  208.         tokens.append(Token(TT_DIV, pos_start=self.pos))
  209.         self.advance()
  210.       elif self.current_char == '**':
  211.         tokens.append(Token(TT_POW, pos_start=self.pos))
  212.         self.advance()
  213.       elif self.current_char == '(':
  214.         tokens.append(Token(TT_LPAREN, pos_start=self.pos))
  215.         self.advance()
  216.       elif self.current_char == ')':
  217.         tokens.append(Token(TT_RPAREN, pos_start=self.pos))
  218.         self.advance()
  219.       elif self.current_char == '[':
  220.         tokens.append(Token(TT_LSQUARE, pos_start=self.pos))
  221.         self.advance()
  222.       elif self.current_char == ']':
  223.         tokens.append(Token(TT_RSQUARE, pos_start=self.pos))
  224.         self.advance()
  225.       elif self.current_char == '!':
  226.         token, error = self.make_not_equals()
  227.         if error: return [], error
  228.         tokens.append(token)
  229.       elif self.current_char == '=':
  230.         tokens.append(self.make_equals())
  231.       elif self.current_char == '<':
  232.         tokens.append(self.make_less_than())
  233.       elif self.current_char == '>':
  234.         tokens.append(self.make_greater_than())
  235.       elif self.current_char == ',':
  236.         tokens.append(Token(TT_COMMA, pos_start=self.pos))
  237.         self.advance()
  238.       elif self.current_char == '=<':
  239.         tokens.append(self.make_less_than() or self.make_equals())
  240.       elif self.current_char == '>=':
  241.         tokens.append(self.make_greater_than() or self.make_equals())
  242.       else:
  243.         pos_start = self.pos.copy()
  244.         char = self.current_char
  245.         self.advance()
  246.         return [], IllegalCharError(pos_start, self.pos, "'" + char + "'")
  247.  
  248.     tokens.append(Token(TT_EOF, pos_start=self.pos))
  249.     return tokens, None
  250.  
  251.   def make_number(self):
  252.     num_str = ''
  253.     dot_count = 0
  254.     pos_start = self.pos.copy()
  255.  
  256.     while self.current_char != None and self.current_char in DIGITS + '.':
  257.       if self.current_char == '.':
  258.         if dot_count == 1: break
  259.         dot_count += 1
  260.       num_str += self.current_char
  261.       self.advance()
  262.  
  263.     if dot_count == 0:
  264.       return Token(TT_INT, int(num_str), pos_start, self.pos)
  265.     else:
  266.       return Token(TT_FLOAT, float(num_str), pos_start, self.pos)
  267.  
  268.   def make_string(self):
  269.     string = ''
  270.     pos_start = self.pos.copy()
  271.     escape_character = False
  272.     self.advance()
  273.  
  274.     escape_characters = {
  275.       'n': '\n',
  276.       't': '\t'
  277.     }
  278.  
  279.     while self.current_char != None and (self.current_char != '"' or escape_character):
  280.       if escape_character:
  281.         string += escape_characters.get(self.current_char, self.current_char)
  282.       else:
  283.         if self.current_char == '\\':
  284.           escape_character = True
  285.         else:
  286.           string += self.current_char
  287.       self.advance()
  288.       escape_character = False
  289.    
  290.     self.advance()
  291.     return Token(TT_STRING, string, pos_start, self.pos)
  292.  
  293.   def make_identifier(self):
  294.     id_str = ''
  295.     pos_start = self.pos.copy()
  296.  
  297.     while self.current_char != None and self.current_char in LETTERS_DIGITS + '_':
  298.       id_str += self.current_char
  299.       self.advance()
  300.  
  301.     tok_type = TT_KEYWORD if id_str in KEYWORDS else TT_IDENTIFIER
  302.     return Token(tok_type, id_str, pos_start, self.pos)
  303.  
  304.   def make_minus_or_arrow(self):
  305.     tok_type = TT_MINUS
  306.     pos_start = self.pos.copy()
  307.     self.advance()
  308.  
  309.     if self.current_char == '>':
  310.       self.advance()
  311.       tok_type = TT_ARROW
  312.  
  313.     return Token(tok_type, pos_start=pos_start, pos_end=self.pos)
  314.  
  315.   def make_not_equals(self):
  316.     pos_start = self.pos.copy()
  317.     self.advance()
  318.  
  319.     if self.current_char == '=':
  320.       self.advance()
  321.       return Token(TT_NE, pos_start=pos_start, pos_end=self.pos), None
  322.  
  323.     self.advance()
  324.     return None, ExpectedCharError(pos_start, self.pos, "'=' (after '!')")
  325.  
  326.   def make_equals(self):
  327.     tok_type = TT_EQ
  328.     pos_start = self.pos.copy()
  329.     self.advance()
  330.  
  331.     if self.current_char == '=':
  332.       self.advance()
  333.       tok_type = TT_EE
  334.  
  335.     return Token(tok_type, pos_start=pos_start, pos_end=self.pos)
  336.  
  337.   def make_less_than(self):
  338.     tok_type = TT_LT
  339.     pos_start = self.pos.copy()
  340.     self.advance()
  341.  
  342.     if self.current_char == '=':
  343.       self.advance()
  344.       tok_type = TT_LTE
  345.  
  346.     return Token(tok_type, pos_start=pos_start, pos_end=self.pos)
  347.  
  348.   def make_greater_than(self):
  349.     tok_type = TT_GT
  350.     pos_start = self.pos.copy()
  351.     self.advance()
  352.  
  353.     if self.current_char == '=':
  354.       self.advance()
  355.       tok_type = TT_GTE
  356.  
  357.     return Token(tok_type, pos_start=pos_start, pos_end=self.pos)
  358.  
  359.   def skip_comment(self):
  360.     self.advance()
  361.  
  362.     while self.current_char != '\n':
  363.       self.advance()
  364.  
  365.     self.advance()
  366. #######################################
  367. # NODES
  368. #######################################
  369.  
  370. class NumberNode:
  371.   def __init__(self, tok):
  372.     self.tok = tok
  373.  
  374.     self.pos_start = self.tok.pos_start
  375.     self.pos_end = self.tok.pos_end
  376.  
  377.   def __repr__(self):
  378.     return f'{self.tok}'
  379.  
  380. class StringNode:
  381.   def __init__(self, tok):
  382.     self.tok = tok
  383.  
  384.     self.pos_start = self.tok.pos_start
  385.     self.pos_end = self.tok.pos_end
  386.  
  387.   def __repr__(self):
  388.     return f'{self.tok}'
  389.  
  390. class ListNode:
  391.   def __init__(self, element_nodes, pos_start, pos_end):
  392.     self.element_nodes = element_nodes
  393.  
  394.     self.pos_start = pos_start
  395.     self.pos_end = pos_end
  396.  
  397. class VarAccessNode:
  398.   def __init__(self, var_name_tok):
  399.     self.var_name_tok = var_name_tok
  400.  
  401.     self.pos_start = self.var_name_tok.pos_start
  402.     self.pos_end = self.var_name_tok.pos_end
  403.  
  404. class VarAssignNode:
  405.   def __init__(self, var_name_tok, value_node):
  406.     self.var_name_tok = var_name_tok
  407.     self.value_node = value_node
  408.  
  409.     self.pos_start = self.var_name_tok.pos_start
  410.     self.pos_end = self.value_node.pos_end
  411.  
  412. class BinOpNode:
  413.   def __init__(self, left_node, op_tok, right_node):
  414.     self.left_node = left_node
  415.     self.op_tok = op_tok
  416.     self.right_node = right_node
  417.  
  418.     self.pos_start = self.left_node.pos_start
  419.     self.pos_end = self.right_node.pos_end
  420.  
  421.   def __repr__(self):
  422.     return f'({self.left_node}, {self.op_tok}, {self.right_node})'
  423.  
  424. class UnaryOpNode:
  425.   def __init__(self, op_tok, node):
  426.     self.op_tok = op_tok
  427.     self.node = node
  428.  
  429.     self.pos_start = self.op_tok.pos_start
  430.     self.pos_end = node.pos_end
  431.  
  432.   def __repr__(self):
  433.     return f'({self.op_tok}, {self.node})'
  434.  
  435. class IfNode:
  436.   def __init__(self, cases, else_case):
  437.     self.cases = cases
  438.     self.else_case = else_case
  439.  
  440.     self.pos_start = self.cases[0][0].pos_start
  441.     self.pos_end = (self.else_case or self.cases[len(self.cases) - 1])[0].pos_end
  442.  
  443. class ForNode:
  444.   def __init__(self, var_name_tok, start_value_node, end_value_node, step_value_node, body_node, should_return_null):
  445.     self.var_name_tok = var_name_tok
  446.     self.start_value_node = start_value_node
  447.     self.end_value_node = end_value_node
  448.     self.step_value_node = step_value_node
  449.     self.body_node = body_node
  450.     self.should_return_null = should_return_null
  451.  
  452.     self.pos_start = self.var_name_tok.pos_start
  453.     self.pos_end = self.body_node.pos_end
  454.  
  455. class WhileNode:
  456.   def __init__(self, condition_node, body_node, should_return_null):
  457.     self.condition_node = condition_node
  458.     self.body_node = body_node
  459.     self.should_return_null = should_return_null
  460.  
  461.     self.pos_start = self.condition_node.pos_start
  462.     self.pos_end = self.body_node.pos_end
  463.  
  464. class FuncDefNode:
  465.   def __init__(self, var_name_tok, arg_name_toks, body_node, should_auto_return):
  466.     self.var_name_tok = var_name_tok
  467.     self.arg_name_toks = arg_name_toks
  468.     self.body_node = body_node
  469.     self.should_auto_return = should_auto_return
  470.  
  471.     if self.var_name_tok:
  472.       self.pos_start = self.var_name_tok.pos_start
  473.     elif len(self.arg_name_toks) > 0:
  474.       self.pos_start = self.arg_name_toks[0].pos_start
  475.     else:
  476.       self.pos_start = self.body_node.pos_start
  477.  
  478.     self.pos_end = self.body_node.pos_end
  479.  
  480. class CallNode:
  481.   def __init__(self, node_to_call, arg_nodes):
  482.     self.node_to_call = node_to_call
  483.     self.arg_nodes = arg_nodes
  484.  
  485.     self.pos_start = self.node_to_call.pos_start
  486.  
  487.     if len(self.arg_nodes) > 0:
  488.       self.pos_end = self.arg_nodes[len(self.arg_nodes) - 1].pos_end
  489.     else:
  490.       self.pos_end = self.node_to_call.pos_end
  491.  
  492. class ReturnNode:
  493.   def __init__(self, node_to_return, pos_start, pos_end):
  494.     self.node_to_return = node_to_return
  495.  
  496.     self.pos_start = pos_start
  497.     self.pos_end = pos_end
  498.  
  499. class ContinueNode:
  500.   def __init__(self, pos_start, pos_end):
  501.     self.pos_start = pos_start
  502.     self.pos_end = pos_end
  503.  
  504. class BreakNode:
  505.   def __init__(self, pos_start, pos_end):
  506.     self.pos_start = pos_start
  507.     self.pos_end = pos_end
  508.  
  509. #######################################
  510. # PARSE RESULT
  511. #######################################
  512.  
  513. class ParseResult:
  514.   def __init__(self):
  515.     self.error = None
  516.     self.node = None
  517.     self.last_registered_advance_count = 0
  518.     self.advance_count = 0
  519.     self.to_reverse_count = 0
  520.  
  521.   def register_advancement(self):
  522.     self.last_registered_advance_count = 1
  523.     self.advance_count += 1
  524.  
  525.   def register(self, res):
  526.     self.last_registered_advance_count = res.advance_count
  527.     self.advance_count += res.advance_count
  528.     if res.error: self.error = res.error
  529.     return res.node
  530.  
  531.   def try_register(self, res):
  532.     if res.error:
  533.       self.to_reverse_count = res.advance_count
  534.       return None
  535.     return self.register(res)
  536.  
  537.   def success(self, node):
  538.     self.node = node
  539.     return self
  540.  
  541.   def failure(self, error):
  542.     if not self.error or self.last_registered_advance_count == 0:
  543.       self.error = error
  544.     return self
  545.  
  546. #######################################
  547. # PARSER
  548. #######################################
  549.  
  550. class Parser:
  551.   def __init__(self, tokens):
  552.     self.tokens = tokens
  553.     self.tok_idx = -1
  554.     self.advance()
  555.  
  556.   def advance(self):
  557.     self.tok_idx += 1
  558.     self.update_current_tok()
  559.     return self.current_tok
  560.  
  561.   def reverse(self, amount=1):
  562.     self.tok_idx -= amount
  563.     self.update_current_tok()
  564.     return self.current_tok
  565.  
  566.   def update_current_tok(self):
  567.     if self.tok_idx >= 0 and self.tok_idx < len(self.tokens):
  568.       self.current_tok = self.tokens[self.tok_idx]
  569.    
  570.   def parse(self):
  571.     res = self.statements()
  572.     if not res.error and self.current_tok.type != TT_EOF:
  573.       return res.failure(InvalidSyntaxError(
  574.         self.current_tok.pos_start, self.current_tok.pos_end,
  575.         "Token cannot appear after previous tokens"
  576.       ))
  577.     return res
  578.  
  579.   ###################################
  580.  
  581.   def statements(self):
  582.     res = ParseResult()
  583.     statements = []
  584.     pos_start = self.current_tok.pos_start.copy()
  585.  
  586.     while self.current_tok.type == TT_NEWLINE:
  587.       res.register_advancement()
  588.       self.advance()
  589.  
  590.     statement = res.register(self.statement())
  591.     if res.error: return res
  592.     statements.append(statement)
  593.  
  594.     more_statements = True
  595.  
  596.     while True:
  597.       newline_count = 0
  598.       while self.current_tok.type == TT_NEWLINE:
  599.         res.register_advancement()
  600.         self.advance()
  601.         newline_count += 1
  602.       if newline_count == 0:
  603.         more_statements = False
  604.      
  605.       if not more_statements: break
  606.       statement = res.try_register(self.statement())
  607.       if not statement:
  608.         self.reverse(res.to_reverse_count)
  609.         more_statements = False
  610.         continue
  611.       statements.append(statement)
  612.  
  613.     return res.success(ListNode(
  614.       statements,
  615.       pos_start,
  616.       self.current_tok.pos_end.copy()
  617.     ))
  618.  
  619.   def statement(self):
  620.     res = ParseResult()
  621.     pos_start = self.current_tok.pos_start.copy()
  622.  
  623.     if self.current_tok.matches(TT_KEYWORD, 'return'):
  624.       res.register_advancement()
  625.       self.advance()
  626.  
  627.       expr = res.try_register(self.expr())
  628.       if not expr:
  629.         self.reverse(res.to_reverse_count)
  630.       return res.success(ReturnNode(expr, pos_start, self.current_tok.pos_start.copy()))
  631.    
  632.     if self.current_tok.matches(TT_KEYWORD, 'continue'):
  633.       res.register_advancement()
  634.       self.advance()
  635.       return res.success(ContinueNode(pos_start, self.current_tok.pos_start.copy()))
  636.      
  637.     if self.current_tok.matches(TT_KEYWORD, 'break'):
  638.       res.register_advancement()
  639.       self.advance()
  640.       return res.success(BreakNode(pos_start, self.current_tok.pos_start.copy()))
  641.  
  642.     expr = res.register(self.expr())
  643.     if res.error:
  644.       return res.failure(InvalidSyntaxError(
  645.         self.current_tok.pos_start, self.current_tok.pos_end,
  646.         "Expected 'return', 'continue', 'break', 'var', 'if', 'for', 'while', 'func', int, float, identifier, '+', '-', '(', '[' or 'NOT'"
  647.       ))
  648.     return res.success(expr)
  649.  
  650.   def expr(self):
  651.     res = ParseResult()
  652.  
  653.     if self.current_tok.matches(TT_KEYWORD, 'var'):
  654.       res.register_advancement()
  655.       self.advance()
  656.  
  657.       if self.current_tok.type != TT_IDENTIFIER:
  658.         return res.failure(InvalidSyntaxError(
  659.           self.current_tok.pos_start, self.current_tok.pos_end,
  660.           "Expected identifier"
  661.         ))
  662.  
  663.       var_name = self.current_tok
  664.       res.register_advancement()
  665.       self.advance()
  666.  
  667.       if self.current_tok.type != TT_EQ:
  668.         return res.failure(InvalidSyntaxError(
  669.           self.current_tok.pos_start, self.current_tok.pos_end,
  670.           "Expected '='"
  671.         ))
  672.  
  673.       res.register_advancement()
  674.       self.advance()
  675.       expr = res.register(self.expr())
  676.       if res.error: return res
  677.       return res.success(VarAssignNode(var_name, expr))
  678.  
  679.     node = res.register(self.bin_op(self.comp_expr, ((TT_KEYWORD, 'and'), (TT_KEYWORD, 'or'))))
  680.  
  681.     if res.error:
  682.       return res.failure(InvalidSyntaxError(
  683.         self.current_tok.pos_start, self.current_tok.pos_end,
  684.         "Expected 'var', 'if', 'for', 'while', 'func', int, float, identifier, '+', '-', '(', '[' or 'NOT'"
  685.       ))
  686.  
  687.     return res.success(node)
  688.  
  689.   def comp_expr(self):
  690.     res = ParseResult()
  691.  
  692.     if self.current_tok.matches(TT_KEYWORD, 'not'):
  693.       op_tok = self.current_tok
  694.       res.register_advancement()
  695.       self.advance()
  696.  
  697.       node = res.register(self.comp_expr())
  698.       if res.error: return res
  699.       return res.success(UnaryOpNode(op_tok, node))
  700.    
  701.     node = res.register(self.bin_op(self.arith_expr, (TT_EE, TT_NE, TT_LT, TT_GT, TT_LTE, TT_GTE)))
  702.    
  703.     if res.error:
  704.       return res.failure(InvalidSyntaxError(
  705.         self.current_tok.pos_start, self.current_tok.pos_end,
  706.         "Expected int, float, identifier, '+', '-', '(', '[', 'if', 'for', 'while', 'dunc' or 'not'"
  707.       ))
  708.  
  709.     return res.success(node)
  710.  
  711.   def arith_expr(self):
  712.     return self.bin_op(self.term, (TT_PLUS, TT_MINUS))
  713.  
  714.   def term(self):
  715.     return self.bin_op(self.factor, (TT_MUL, TT_DIV))
  716.  
  717.   def factor(self):
  718.     res = ParseResult()
  719.     tok = self.current_tok
  720.  
  721.     if tok.type in (TT_PLUS, TT_MINUS):
  722.       res.register_advancement()
  723.       self.advance()
  724.       factor = res.register(self.factor())
  725.       if res.error: return res
  726.       return res.success(UnaryOpNode(tok, factor))
  727.  
  728.     return self.power()
  729.  
  730.   def power(self):
  731.     return self.bin_op(self.call, (TT_POW, ), self.factor)
  732.  
  733.   def call(self):
  734.     res = ParseResult()
  735.     atom = res.register(self.atom())
  736.     if res.error: return res
  737.  
  738.     if self.current_tok.type == TT_LPAREN:
  739.       res.register_advancement()
  740.       self.advance()
  741.       arg_nodes = []
  742.  
  743.       if self.current_tok.type == TT_RPAREN:
  744.         res.register_advancement()
  745.         self.advance()
  746.       else:
  747.         arg_nodes.append(res.register(self.expr()))
  748.         if res.error:
  749.           return res.failure(InvalidSyntaxError(
  750.             self.current_tok.pos_start, self.current_tok.pos_end,
  751.             "Expected ')', 'var', 'if', 'for', 'while', 'func', int, float, identifier, '+', '-', '(', '[' or 'not'"
  752.           ))
  753.  
  754.         while self.current_tok.type == TT_COMMA:
  755.           res.register_advancement()
  756.           self.advance()
  757.  
  758.           arg_nodes.append(res.register(self.expr()))
  759.           if res.error: return res
  760.  
  761.         if self.current_tok.type != TT_RPAREN:
  762.           return res.failure(InvalidSyntaxError(
  763.             self.current_tok.pos_start, self.current_tok.pos_end,
  764.             f"Expected ',' or ')'"
  765.           ))
  766.  
  767.         res.register_advancement()
  768.         self.advance()
  769.       return res.success(CallNode(atom, arg_nodes))
  770.     return res.success(atom)
  771.  
  772.   def atom(self):
  773.     res = ParseResult()
  774.     tok = self.current_tok
  775.  
  776.     if tok.type in (TT_INT, TT_FLOAT):
  777.       res.register_advancement()
  778.       self.advance()
  779.       return res.success(NumberNode(tok))
  780.  
  781.     elif tok.type == TT_STRING:
  782.       res.register_advancement()
  783.       self.advance()
  784.       return res.success(StringNode(tok))
  785.  
  786.     elif tok.type == TT_IDENTIFIER:
  787.       res.register_advancement()
  788.       self.advance()
  789.       return res.success(VarAccessNode(tok))
  790.  
  791.     elif tok.type == TT_LPAREN:
  792.       res.register_advancement()
  793.       self.advance()
  794.       expr = res.register(self.expr())
  795.       if res.error: return res
  796.       if self.current_tok.type == TT_RPAREN:
  797.         res.register_advancement()
  798.         self.advance()
  799.         return res.success(expr)
  800.       else:
  801.         return res.failure(InvalidSyntaxError(
  802.           self.current_tok.pos_start, self.current_tok.pos_end,
  803.           "Expected ')'"
  804.         ))
  805.  
  806.     elif tok.type == TT_LSQUARE:
  807.       list_expr = res.register(self.list_expr())
  808.       if res.error: return res
  809.       return res.success(list_expr)
  810.    
  811.     elif tok.matches(TT_KEYWORD, 'if'):
  812.       if_expr = res.register(self.if_expr())
  813.       if res.error: return res
  814.       return res.success(if_expr)
  815.  
  816.     elif tok.matches(TT_KEYWORD, 'for'):
  817.       for_expr = res.register(self.for_expr())
  818.       if res.error: return res
  819.       return res.success(for_expr)
  820.  
  821.     elif tok.matches(TT_KEYWORD, 'while'):
  822.       while_expr = res.register(self.while_expr())
  823.       if res.error: return res
  824.       return res.success(while_expr)
  825.  
  826.     elif tok.matches(TT_KEYWORD, 'func'):
  827.       func_def = res.register(self.func_def())
  828.       if res.error: return res
  829.       return res.success(func_def)
  830.  
  831.     return res.failure(InvalidSyntaxError(
  832.       tok.pos_start, tok.pos_end,
  833.       "Expected int, float, identifier, '+', '-', '(', '[', if', 'for', 'while', 'func'"
  834.     ))
  835.  
  836.   def list_expr(self):
  837.     res = ParseResult()
  838.     element_nodes = []
  839.     pos_start = self.current_tok.pos_start.copy()
  840.  
  841.     if self.current_tok.type != TT_LSQUARE:
  842.       return res.failure(InvalidSyntaxError(
  843.         self.current_tok.pos_start, self.current_tok.pos_end,
  844.         f"Expected '['"
  845.       ))
  846.  
  847.     res.register_advancement()
  848.     self.advance()
  849.  
  850.     if self.current_tok.type == TT_RSQUARE:
  851.       res.register_advancement()
  852.       self.advance()
  853.     else:
  854.       element_nodes.append(res.register(self.expr()))
  855.       if res.error:
  856.         return res.failure(InvalidSyntaxError(
  857.           self.current_tok.pos_start, self.current_tok.pos_end,
  858.           "Expected ']', 'var', 'if', 'for', 'while', 'func', int, float, identifier, '+', '-', '(', '[' or 'not'"
  859.         ))
  860.  
  861.       while self.current_tok.type == TT_COMMA:
  862.         res.register_advancement()
  863.         self.advance()
  864.  
  865.         element_nodes.append(res.register(self.expr()))
  866.         if res.error: return res
  867.  
  868.       if self.current_tok.type != TT_RSQUARE:
  869.         return res.failure(InvalidSyntaxError(
  870.           self.current_tok.pos_start, self.current_tok.pos_end,
  871.           f"Expected ',' or ']'"
  872.         ))
  873.  
  874.       res.register_advancement()
  875.       self.advance()
  876.  
  877.     return res.success(ListNode(
  878.       element_nodes,
  879.       pos_start,
  880.       self.current_tok.pos_end.copy()
  881.     ))
  882.  
  883.   def if_expr(self):
  884.     res = ParseResult()
  885.     all_cases = res.register(self.if_expr_cases('if'))
  886.     if res.error: return res
  887.     cases, else_case = all_cases
  888.     return res.success(IfNode(cases, else_case))
  889.  
  890.   def if_expr_b(self):
  891.     return self.if_expr_cases('otherif')
  892.    
  893.   def if_expr_c(self):
  894.     res = ParseResult()
  895.     else_case = None
  896.  
  897.     if self.current_tok.matches(TT_KEYWORD, 'otherwise'):
  898.       res.register_advancement()
  899.       self.advance()
  900.  
  901.       if self.current_tok.type == TT_NEWLINE:
  902.         res.register_advancement()
  903.         self.advance()
  904.  
  905.         statements = res.register(self.statements())
  906.         if res.error: return res
  907.         else_case = (statements, True)
  908.  
  909.         if self.current_tok.matches(TT_KEYWORD, 'end'):
  910.           res.register_advancement()
  911.           self.advance()
  912.         else:
  913.           return res.failure(InvalidSyntaxError(
  914.             self.current_tok.pos_start, self.current_tok.pos_end,
  915.             "Expected 'end'"
  916.           ))
  917.       else:
  918.         expr = res.register(self.statement())
  919.         if res.error: return res
  920.         else_case = (expr, False)
  921.  
  922.     return res.success(else_case)
  923.  
  924.   def if_expr_b_or_c(self):
  925.     res = ParseResult()
  926.     cases, else_case = [], None
  927.  
  928.     if self.current_tok.matches(TT_KEYWORD, 'otherif'):
  929.       all_cases = res.register(self.if_expr_b())
  930.       if res.error: return res
  931.       cases, else_case = all_cases
  932.     else:
  933.       else_case = res.register(self.if_expr_c())
  934.       if res.error: return res
  935.    
  936.     return res.success((cases, else_case))
  937.  
  938.   def if_expr_cases(self, case_keyword):
  939.     res = ParseResult()
  940.     cases = []
  941.     else_case = None
  942.  
  943.     if not self.current_tok.matches(TT_KEYWORD, case_keyword):
  944.       return res.failure(InvalidSyntaxError(
  945.         self.current_tok.pos_start, self.current_tok.pos_end,
  946.         f"Expected '{case_keyword}'"
  947.       ))
  948.  
  949.     res.register_advancement()
  950.     self.advance()
  951.  
  952.     condition = res.register(self.expr())
  953.     if res.error: return res
  954.  
  955.     if not self.current_tok.matches(TT_KEYWORD, 'then'):
  956.       return res.failure(InvalidSyntaxError(
  957.         self.current_tok.pos_start, self.current_tok.pos_end,
  958.         f"Expected 'then'"
  959.       ))
  960.  
  961.     res.register_advancement()
  962.     self.advance()
  963.  
  964.     if self.current_tok.type == TT_NEWLINE:
  965.       res.register_advancement()
  966.       self.advance()
  967.  
  968.       statements = res.register(self.statements())
  969.       if res.error: return res
  970.       cases.append((condition, statements, True))
  971.  
  972.       if self.current_tok.matches(TT_KEYWORD, 'end'):
  973.         res.register_advancement()
  974.         self.advance()
  975.       else:
  976.         all_cases = res.register(self.if_expr_b_or_c())
  977.         if res.error: return res
  978.         new_cases, else_case = all_cases
  979.         cases.extend(new_cases)
  980.     else:
  981.       expr = res.register(self.statement())
  982.       if res.error: return res
  983.       cases.append((condition, expr, False))
  984.  
  985.       all_cases = res.register(self.if_expr_b_or_c())
  986.       if res.error: return res
  987.       new_cases, else_case = all_cases
  988.       cases.extend(new_cases)
  989.  
  990.     return res.success((cases, else_case))
  991.  
  992.   def for_expr(self):
  993.     res = ParseResult()
  994.  
  995.     if not self.current_tok.matches(TT_KEYWORD, 'for'):
  996.       return res.failure(InvalidSyntaxError(
  997.         self.current_tok.pos_start, self.current_tok.pos_end,
  998.         f"Expected 'for'"
  999.       ))
  1000.  
  1001.     res.register_advancement()
  1002.     self.advance()
  1003.  
  1004.     if self.current_tok.type != TT_IDENTIFIER:
  1005.       return res.failure(InvalidSyntaxError(
  1006.         self.current_tok.pos_start, self.current_tok.pos_end,
  1007.         f"Expected identifier"
  1008.       ))
  1009.  
  1010.     var_name = self.current_tok
  1011.     res.register_advancement()
  1012.     self.advance()
  1013.  
  1014.     if self.current_tok.type != TT_EQ:
  1015.       return res.failure(InvalidSyntaxError(
  1016.         self.current_tok.pos_start, self.current_tok.pos_end,
  1017.         f"Expected '='"
  1018.       ))
  1019.    
  1020.     res.register_advancement()
  1021.     self.advance()
  1022.  
  1023.     start_value = res.register(self.expr())
  1024.     if res.error: return res
  1025.  
  1026.     if not self.current_tok.matches(TT_KEYWORD, 'to'):
  1027.       return res.failure(InvalidSyntaxError(
  1028.         self.current_tok.pos_start, self.current_tok.pos_end,
  1029.         f"Expected 'to'"
  1030.       ))
  1031.    
  1032.     res.register_advancement()
  1033.     self.advance()
  1034.  
  1035.     end_value = res.register(self.expr())
  1036.     if res.error: return res
  1037.  
  1038.     if self.current_tok.matches(TT_KEYWORD, 'step'):
  1039.       res.register_advancement()
  1040.       self.advance()
  1041.  
  1042.       step_value = res.register(self.expr())
  1043.       if res.error: return res
  1044.     else:
  1045.       step_value = None
  1046.  
  1047.     if not self.current_tok.matches(TT_KEYWORD, 'then'):
  1048.       return res.failure(InvalidSyntaxError(
  1049.         self.current_tok.pos_start, self.current_tok.pos_end,
  1050.         f"Expected 'then'"
  1051.       ))
  1052.  
  1053.     res.register_advancement()
  1054.     self.advance()
  1055.  
  1056.     if self.current_tok.type == TT_NEWLINE:
  1057.       res.register_advancement()
  1058.       self.advance()
  1059.  
  1060.       body = res.register(self.statements())
  1061.       if res.error: return res
  1062.  
  1063.       if not self.current_tok.matches(TT_KEYWORD, 'end'):
  1064.         return res.failure(InvalidSyntaxError(
  1065.           self.current_tok.pos_start, self.current_tok.pos_end,
  1066.           f"Expected 'end'"
  1067.         ))
  1068.  
  1069.       res.register_advancement()
  1070.       self.advance()
  1071.  
  1072.       return res.success(ForNode(var_name, start_value, end_value, step_value, body, True))
  1073.    
  1074.     body = res.register(self.statement())
  1075.     if res.error: return res
  1076.  
  1077.     return res.success(ForNode(var_name, start_value, end_value, step_value, body, False))
  1078.  
  1079.   def while_expr(self):
  1080.     res = ParseResult()
  1081.  
  1082.     if not self.current_tok.matches(TT_KEYWORD, 'while'):
  1083.       return res.failure(InvalidSyntaxError(
  1084.         self.current_tok.pos_start, self.current_tok.pos_end,
  1085.         f"Expected 'while'"
  1086.       ))
  1087.  
  1088.     res.register_advancement()
  1089.     self.advance()
  1090.  
  1091.     condition = res.register(self.expr())
  1092.     if res.error: return res
  1093.  
  1094.     if not self.current_tok.matches(TT_KEYWORD, 'then'):
  1095.       return res.failure(InvalidSyntaxError(
  1096.         self.current_tok.pos_start, self.current_tok.pos_end,
  1097.         f"Expected 'then'"
  1098.       ))
  1099.  
  1100.     res.register_advancement()
  1101.     self.advance()
  1102.  
  1103.     if self.current_tok.type == TT_NEWLINE:
  1104.       res.register_advancement()
  1105.       self.advance()
  1106.  
  1107.       body = res.register(self.statements())
  1108.       if res.error: return res
  1109.  
  1110.       if not self.current_tok.matches(TT_KEYWORD, 'end'):
  1111.         return res.failure(InvalidSyntaxError(
  1112.           self.current_tok.pos_start, self.current_tok.pos_end,
  1113.           f"Expected 'end'"
  1114.         ))
  1115.  
  1116.       res.register_advancement()
  1117.       self.advance()
  1118.  
  1119.       return res.success(WhileNode(condition, body, True))
  1120.    
  1121.     body = res.register(self.statement())
  1122.     if res.error: return res
  1123.  
  1124.     return res.success(WhileNode(condition, body, False))
  1125.  
  1126.   def func_def(self):
  1127.     res = ParseResult()
  1128.  
  1129.     if not self.current_tok.matches(TT_KEYWORD, 'func'):
  1130.       return res.failure(InvalidSyntaxError(
  1131.         self.current_tok.pos_start, self.current_tok.pos_end,
  1132.         f"Expected 'func'"
  1133.       ))
  1134.  
  1135.     res.register_advancement()
  1136.     self.advance()
  1137.  
  1138.     if self.current_tok.type == TT_IDENTIFIER:
  1139.       var_name_tok = self.current_tok
  1140.       res.register_advancement()
  1141.       self.advance()
  1142.       if self.current_tok.type != TT_LPAREN:
  1143.         return res.failure(InvalidSyntaxError(
  1144.           self.current_tok.pos_start, self.current_tok.pos_end,
  1145.           f"Expected '('"
  1146.         ))
  1147.     else:
  1148.       var_name_tok = None
  1149.       if self.current_tok.type != TT_LPAREN:
  1150.         return res.failure(InvalidSyntaxError(
  1151.           self.current_tok.pos_start, self.current_tok.pos_end,
  1152.           f"Expected identifier or '('"
  1153.         ))
  1154.    
  1155.     res.register_advancement()
  1156.     self.advance()
  1157.     arg_name_toks = []
  1158.  
  1159.     if self.current_tok.type == TT_IDENTIFIER:
  1160.       arg_name_toks.append(self.current_tok)
  1161.       res.register_advancement()
  1162.       self.advance()
  1163.      
  1164.       while self.current_tok.type == TT_COMMA:
  1165.         res.register_advancement()
  1166.         self.advance()
  1167.  
  1168.         if self.current_tok.type != TT_IDENTIFIER:
  1169.           return res.failure(InvalidSyntaxError(
  1170.             self.current_tok.pos_start, self.current_tok.pos_end,
  1171.             f"Expected identifier"
  1172.           ))
  1173.  
  1174.         arg_name_toks.append(self.current_tok)
  1175.         res.register_advancement()
  1176.         self.advance()
  1177.      
  1178.       if self.current_tok.type != TT_RPAREN:
  1179.         return res.failure(InvalidSyntaxError(
  1180.           self.current_tok.pos_start, self.current_tok.pos_end,
  1181.           f"Expected ',' or ')'"
  1182.         ))
  1183.     else:
  1184.       if self.current_tok.type != TT_RPAREN:
  1185.         return res.failure(InvalidSyntaxError(
  1186.           self.current_tok.pos_start, self.current_tok.pos_end,
  1187.           f"Expected identifier or ')'"
  1188.         ))
  1189.  
  1190.     res.register_advancement()
  1191.     self.advance()
  1192.  
  1193.     if self.current_tok.type == TT_ARROW:
  1194.       res.register_advancement()
  1195.       self.advance()
  1196.  
  1197.       body = res.register(self.expr())
  1198.       if res.error: return res
  1199.  
  1200.       return res.success(FuncDefNode(
  1201.         var_name_tok,
  1202.         arg_name_toks,
  1203.         body,
  1204.         True
  1205.       ))
  1206.    
  1207.     if self.current_tok.type != TT_NEWLINE:
  1208.       return res.failure(InvalidSyntaxError(
  1209.         self.current_tok.pos_start, self.current_tok.pos_end,
  1210.         f"Expected '->' or NEWLINE"
  1211.       ))
  1212.  
  1213.     res.register_advancement()
  1214.     self.advance()
  1215.  
  1216.     body = res.register(self.statements())
  1217.     if res.error: return res
  1218.  
  1219.     if not self.current_tok.matches(TT_KEYWORD, 'end'):
  1220.       return res.failure(InvalidSyntaxError(
  1221.         self.current_tok.pos_start, self.current_tok.pos_end,
  1222.         f"Expected 'end'"
  1223.       ))
  1224.  
  1225.     res.register_advancement()
  1226.     self.advance()
  1227.    
  1228.     return res.success(FuncDefNode(
  1229.       var_name_tok,
  1230.       arg_name_toks,
  1231.       body,
  1232.       False
  1233.     ))
  1234.  
  1235.   ###################################
  1236.  
  1237.   def bin_op(self, func_a, ops, func_b=None):
  1238.     if func_b == None:
  1239.       func_b = func_a
  1240.    
  1241.     res = ParseResult()
  1242.     left = res.register(func_a())
  1243.     if res.error: return res
  1244.  
  1245.     while self.current_tok.type in ops or (self.current_tok.type, self.current_tok.value) in ops:
  1246.       op_tok = self.current_tok
  1247.       res.register_advancement()
  1248.       self.advance()
  1249.       right = res.register(func_b())
  1250.       if res.error: return res
  1251.       left = BinOpNode(left, op_tok, right)
  1252.  
  1253.     return res.success(left)
  1254.  
  1255. #######################################
  1256. # RUNTIME RESULT
  1257. #######################################
  1258.  
  1259. class RTResult:
  1260.   def __init__(self):
  1261.     self.reset()
  1262.  
  1263.   def reset(self):
  1264.     self.value = None
  1265.     self.error = None
  1266.     self.func_return_value = None
  1267.     self.loop_should_continue = False
  1268.     self.loop_should_break = False
  1269.  
  1270.   def register(self, res):
  1271.     self.error = res.error
  1272.     self.func_return_value = res.func_return_value
  1273.     self.loop_should_continue = res.loop_should_continue
  1274.     self.loop_should_break = res.loop_should_break
  1275.     return res.value
  1276.  
  1277.   def success(self, value):
  1278.     self.reset()
  1279.     self.value = value
  1280.     return self
  1281.  
  1282.   def success_return(self, value):
  1283.     self.reset()
  1284.     self.func_return_value = value
  1285.     return self
  1286.  
  1287.   def success_continue(self):
  1288.     self.reset()
  1289.     self.loop_should_continue = True
  1290.     return self
  1291.  
  1292.   def success_break(self):
  1293.     self.reset()
  1294.     self.loop_should_break = True
  1295.     return self
  1296.  
  1297.   def failure(self, error):
  1298.     self.reset()
  1299.     self.error = error
  1300.     return self
  1301.  
  1302.   def should_return(self):
  1303.     # Note: this will allow you to continue and break outside the current function
  1304.     return (
  1305.       self.error or
  1306.       self.func_return_value or
  1307.       self.loop_should_continue or
  1308.       self.loop_should_break
  1309.     )
  1310.  
  1311. #######################################
  1312. # VALUES
  1313. #######################################
  1314.  
  1315. class Value:
  1316.   def __init__(self):
  1317.     self.set_pos()
  1318.     self.set_context()
  1319.  
  1320.   def set_pos(self, pos_start=None, pos_end=None):
  1321.     self.pos_start = pos_start
  1322.     self.pos_end = pos_end
  1323.     return self
  1324.  
  1325.   def set_context(self, context=None):
  1326.     self.context = context
  1327.     return self
  1328.  
  1329.   def added_to(self, other):
  1330.     return None, self.illegal_operation(other)
  1331.  
  1332.   def subbed_by(self, other):
  1333.     return None, self.illegal_operation(other)
  1334.  
  1335.   def multed_by(self, other):
  1336.     return None, self.illegal_operation(other)
  1337.  
  1338.   def dived_by(self, other):
  1339.     return None, self.illegal_operation(other)
  1340.  
  1341.   def powed_by(self, other):
  1342.     return None, self.illegal_operation(other)
  1343.  
  1344.   def get_comparison_eq(self, other):
  1345.     return None, self.illegal_operation(other)
  1346.  
  1347.   def get_comparison_ne(self, other):
  1348.     return None, self.illegal_operation(other)
  1349.  
  1350.   def get_comparison_lt(self, other):
  1351.     return None, self.illegal_operation(other)
  1352.  
  1353.   def get_comparison_gt(self, other):
  1354.     return None, self.illegal_operation(other)
  1355.  
  1356.   def get_comparison_lte(self, other):
  1357.     return None, self.illegal_operation(other)
  1358.  
  1359.   def get_comparison_gte(self, other):
  1360.     return None, self.illegal_operation(other)
  1361.  
  1362.   def anded_by(self, other):
  1363.     return None, self.illegal_operation(other)
  1364.  
  1365.   def ored_by(self, other):
  1366.     return None, self.illegal_operation(other)
  1367.  
  1368.   def notted(self, other):
  1369.     return None, self.illegal_operation(other)
  1370.  
  1371.   def execute(self, args):
  1372.     return RTResult().failure(self.illegal_operation())
  1373.  
  1374.   def copy(self):
  1375.     raise Exception('No copy method defined')
  1376.  
  1377.   def is_true(self):
  1378.     return False
  1379.  
  1380.   def illegal_operation(self, other=None):
  1381.     if not other: other = self
  1382.     return RTError(
  1383.       self.pos_start, other.pos_end,
  1384.       'Illegal operation',
  1385.       self.context
  1386.     )
  1387.  
  1388. class Number(Value):
  1389.   def __init__(self, value):
  1390.     super().__init__()
  1391.     self.value = value
  1392.  
  1393.   def added_to(self, other):
  1394.     if isinstance(other, Number):
  1395.       return Number(self.value + other.value).set_context(self.context), None
  1396.     else:
  1397.       return None, Value.illegal_operation(self, other)
  1398.  
  1399.   def subbed_by(self, other):
  1400.     if isinstance(other, Number):
  1401.       return Number(self.value - other.value).set_context(self.context), None
  1402.     else:
  1403.       return None, Value.illegal_operation(self, other)
  1404.  
  1405.   def multed_by(self, other):
  1406.     if isinstance(other, Number):
  1407.       return Number(self.value * other.value).set_context(self.context), None
  1408.     else:
  1409.       return None, Value.illegal_operation(self, other)
  1410.  
  1411.   def dived_by(self, other):
  1412.     if isinstance(other, Number):
  1413.       if other.value == 0:
  1414.         return None, RTError(
  1415.           other.pos_start, other.pos_end,
  1416.           'Division by zero',
  1417.           self.context
  1418.         )
  1419.  
  1420.       return Number(self.value / other.value).set_context(self.context), None
  1421.     else:
  1422.       return None, Value.illegal_operation(self, other)
  1423.  
  1424.   def powed_by(self, other):
  1425.     if isinstance(other, Number):
  1426.       return Number(self.value ** other.value).set_context(self.context), None
  1427.     else:
  1428.       return None, Value.illegal_operation(self, other)
  1429.  
  1430.   def get_comparison_eq(self, other):
  1431.     if isinstance(other, Number):
  1432.       return Number(int(self.value == other.value)).set_context(self.context), None
  1433.     else:
  1434.       return None, Value.illegal_operation(self, other)
  1435.  
  1436.   def get_comparison_ne(self, other):
  1437.     if isinstance(other, Number):
  1438.       return Number(int(self.value != other.value)).set_context(self.context), None
  1439.     else:
  1440.       return None, Value.illegal_operation(self, other)
  1441.  
  1442.   def get_comparison_lt(self, other):
  1443.     if isinstance(other, Number):
  1444.       return Number(int(self.value < other.value)).set_context(self.context), None
  1445.     else:
  1446.       return None, Value.illegal_operation(self, other)
  1447.  
  1448.   def get_comparison_gt(self, other):
  1449.     if isinstance(other, Number):
  1450.       return Number(int(self.value > other.value)).set_context(self.context), None
  1451.     else:
  1452.       return None, Value.illegal_operation(self, other)
  1453.  
  1454.   def get_comparison_lte(self, other):
  1455.     if isinstance(other, Number):
  1456.       return Number(int(self.value <= other.value)).set_context(self.context), None
  1457.     else:
  1458.       return None, Value.illegal_operation(self, other)
  1459.  
  1460.   def get_comparison_gte(self, other):
  1461.     if isinstance(other, Number):
  1462.       return Number(int(self.value >= other.value)).set_context(self.context), None
  1463.     else:
  1464.       return None, Value.illegal_operation(self, other)
  1465.  
  1466.   def anded_by(self, other):
  1467.     if isinstance(other, Number):
  1468.       return Number(int(self.value and other.value)).set_context(self.context), None
  1469.     else:
  1470.       return None, Value.illegal_operation(self, other)
  1471.  
  1472.   def ored_by(self, other):
  1473.     if isinstance(other, Number):
  1474.       return Number(int(self.value or other.value)).set_context(self.context), None
  1475.     else:
  1476.       return None, Value.illegal_operation(self, other)
  1477.  
  1478.   def notted(self):
  1479.     return Number(1 if self.value == 0 else 0).set_context(self.context), None
  1480.  
  1481.   def copy(self):
  1482.     copy = Number(self.value)
  1483.     copy.set_pos(self.pos_start, self.pos_end)
  1484.     copy.set_context(self.context)
  1485.     return copy
  1486.  
  1487.   def is_true(self):
  1488.     return self.value != 0
  1489.  
  1490.   def __str__(self):
  1491.     return str(self.value)
  1492.  
  1493.   def __repr__(self):
  1494.     return str(self.value)
  1495.  
  1496. Number.null = Number(0)
  1497. Number.false = Number(0)
  1498. Number.true = Number(1)
  1499. Number.math_PI = Number(math.pi)
  1500.  
  1501. class String(Value):
  1502.   def __init__(self, value):
  1503.     super().__init__()
  1504.     self.value = value
  1505.  
  1506.   def added_to(self, other):
  1507.     if isinstance(other, String):
  1508.       return String(self.value + other.value).set_context(self.context), None
  1509.     else:
  1510.       return None, Value.illegal_operation(self, other)
  1511.  
  1512.   def multed_by(self, other):
  1513.     if isinstance(other, Number):
  1514.       return String(self.value * other.value).set_context(self.context), None
  1515.     else:
  1516.       return None, Value.illegal_operation(self, other)
  1517.  
  1518.   def is_true(self):
  1519.     return len(self.value) > 0
  1520.  
  1521.   def copy(self):
  1522.     copy = String(self.value)
  1523.     copy.set_pos(self.pos_start, self.pos_end)
  1524.     copy.set_context(self.context)
  1525.     return copy
  1526.  
  1527.   def __str__(self):
  1528.     return self.value
  1529.  
  1530.   def __repr__(self):
  1531.     return f'"{self.value}"'
  1532.  
  1533. class List(Value):
  1534.   def __init__(self, elements):
  1535.     super().__init__()
  1536.     self.elements = elements
  1537.  
  1538.   def added_to(self, other):
  1539.     new_list = self.copy()
  1540.     new_list.elements.append(other)
  1541.     return new_list, None
  1542.  
  1543.   def subbed_by(self, other):
  1544.     if isinstance(other, Number):
  1545.       new_list = self.copy()
  1546.       try:
  1547.         new_list.elements.pop(other.value)
  1548.         return new_list, None
  1549.       except:
  1550.         return None, RTError(
  1551.           other.pos_start, other.pos_end,
  1552.           'Element at this index could not be removed from list because index is out of bounds',
  1553.           self.context
  1554.         )
  1555.     else:
  1556.       return None, Value.illegal_operation(self, other)
  1557.  
  1558.   def multed_by(self, other):
  1559.     if isinstance(other, List):
  1560.       new_list = self.copy()
  1561.       new_list.elements.extend(other.elements)
  1562.       return new_list, None
  1563.     else:
  1564.       return None, Value.illegal_operation(self, other)
  1565.  
  1566.   def dived_by(self, other):
  1567.     if isinstance(other, Number):
  1568.       try:
  1569.         return self.elements[other.value], None
  1570.       except:
  1571.         return None, RTError(
  1572.           other.pos_start, other.pos_end,
  1573.           'Element at this index could not be retrieved from list because index is out of bounds',
  1574.           self.context
  1575.         )
  1576.     else:
  1577.       return None, Value.illegal_operation(self, other)
  1578.  
  1579.   def copy(self):
  1580.     copy = List(self.elements)
  1581.     copy.set_pos(self.pos_start, self.pos_end)
  1582.     copy.set_context(self.context)
  1583.     return copy
  1584.  
  1585.   def __str__(self):
  1586.     return ", ".join([str(x) for x in self.elements])
  1587.  
  1588.   def __repr__(self):
  1589.     return f'[{", ".join([repr(x) for x in self.elements])}]'
  1590.  
  1591. class BaseFunction(Value):
  1592.   def __init__(self, name):
  1593.     super().__init__()
  1594.     self.name = name or "<anonymous>"
  1595.  
  1596.   def generate_new_context(self):
  1597.     new_context = Context(self.name, self.context, self.pos_start)
  1598.     new_context.symbol_table = SymbolTable(new_context.parent.symbol_table)
  1599.     return new_context
  1600.  
  1601.   def check_args(self, arg_names, args):
  1602.     res = RTResult()
  1603.  
  1604.     if len(args) > len(arg_names):
  1605.       return res.failure(RTError(
  1606.         self.pos_start, self.pos_end,
  1607.         f"{len(args) - len(arg_names)} too many args passed into {self}",
  1608.         self.context
  1609.       ))
  1610.    
  1611.     if len(args) < len(arg_names):
  1612.       return res.failure(RTError(
  1613.         self.pos_start, self.pos_end,
  1614.         f"{len(arg_names) - len(args)} too few args passed into {self}",
  1615.         self.context
  1616.       ))
  1617.  
  1618.     return res.success(None)
  1619.  
  1620.   def populate_args(self, arg_names, args, exec_ctx):
  1621.     for i in range(len(args)):
  1622.       arg_name = arg_names[i]
  1623.       arg_value = args[i]
  1624.       arg_value.set_context(exec_ctx)
  1625.       exec_ctx.symbol_table.set(arg_name, arg_value)
  1626.  
  1627.   def check_and_populate_args(self, arg_names, args, exec_ctx):
  1628.     res = RTResult()
  1629.     res.register(self.check_args(arg_names, args))
  1630.     if res.should_return(): return res
  1631.     self.populate_args(arg_names, args, exec_ctx)
  1632.     return res.success(None)
  1633.  
  1634. class Function(BaseFunction):
  1635.   def __init__(self, name, body_node, arg_names, should_auto_return):
  1636.     super().__init__(name)
  1637.     self.body_node = body_node
  1638.     self.arg_names = arg_names
  1639.     self.should_auto_return = should_auto_return
  1640.  
  1641.   def execute(self, args):
  1642.     res = RTResult()
  1643.     interpreter = Interpreter()
  1644.     exec_ctx = self.generate_new_context()
  1645.  
  1646.     res.register(self.check_and_populate_args(self.arg_names, args, exec_ctx))
  1647.     if res.should_return(): return res
  1648.  
  1649.     value = res.register(interpreter.visit(self.body_node, exec_ctx))
  1650.     if res.should_return() and res.func_return_value == None: return res
  1651.  
  1652.     ret_value = (value if self.should_auto_return else None) or res.func_return_value or Number.null
  1653.     return res.success(ret_value)
  1654.  
  1655.   def copy(self):
  1656.     copy = Function(self.name, self.body_node, self.arg_names, self.should_auto_return)
  1657.     copy.set_context(self.context)
  1658.     copy.set_pos(self.pos_start, self.pos_end)
  1659.     return copy
  1660.  
  1661.   def __repr__(self):
  1662.     return f"<function {self.name}>"
  1663.  
  1664. class BuiltInFunction(BaseFunction):
  1665.   def __init__(self, name):
  1666.     super().__init__(name)
  1667.  
  1668.   def execute(self, args):
  1669.     res = RTResult()
  1670.     exec_ctx = self.generate_new_context()
  1671.  
  1672.     method_name = f'execute_{self.name}'
  1673.     method = getattr(self, method_name, self.no_visit_method)
  1674.  
  1675.     res.register(self.check_and_populate_args(method.arg_names, args, exec_ctx))
  1676.     if res.should_return(): return res
  1677.  
  1678.     return_value = res.register(method(exec_ctx))
  1679.     if res.should_return(): return res
  1680.     return res.success(return_value)
  1681.  
  1682.   def no_visit_method(self, node, context):
  1683.     raise Exception(f'No execute_{self.name} method defined')
  1684.  
  1685.   def copy(self):
  1686.     copy = BuiltInFunction(self.name)
  1687.     copy.set_context(self.context)
  1688.     copy.set_pos(self.pos_start, self.pos_end)
  1689.     return copy
  1690.  
  1691.   def __repr__(self):
  1692.     return f"<built-in function {self.name}>"
  1693.  
  1694.   #####################################
  1695.  
  1696.   def execute_print(self, exec_ctx):
  1697.     print(str(exec_ctx.symbol_table.get('value')))
  1698.     return RTResult().success(Number.null)
  1699.   execute_print.arg_names = ['value']
  1700.  
  1701.   def execute_print_ret(self, exec_ctx):
  1702.     return RTResult().success(String(str(exec_ctx.symbol_table.get('value'))))
  1703.   execute_print_ret.arg_names = ['value']
  1704.  
  1705.   def execute_input(self, exec_ctx):
  1706.     text = input()
  1707.     return RTResult().success(String(text))
  1708.   execute_input.arg_names = []
  1709.  
  1710.   def execute_input_int(self, exec_ctx):
  1711.     while True:
  1712.       text = input()
  1713.       try:
  1714.         number = int(text)
  1715.         break
  1716.       except ValueError:
  1717.         print(f"'{text}' must be an integer. Try again!")
  1718.     return RTResult().success(Number(number))
  1719.   execute_input_int.arg_names = []
  1720.  
  1721.   def execute_clear(self, exec_ctx):
  1722.     os.system('cls' if os.name == 'nt' else 'cls')
  1723.     return RTResult().success(Number.null)
  1724.   execute_clear.arg_names = []
  1725.  
  1726.   def execute_is_number(self, exec_ctx):
  1727.     is_number = isinstance(exec_ctx.symbol_table.get("value"), Number)
  1728.     return RTResult().success(Number.true if is_number else Number.false)
  1729.   execute_is_number.arg_names = ["value"]
  1730.  
  1731.   def execute_is_string(self, exec_ctx):
  1732.     is_number = isinstance(exec_ctx.symbol_table.get("value"), String)
  1733.     return RTResult().success(Number.true if is_number else Number.false)
  1734.   execute_is_string.arg_names = ["value"]
  1735.  
  1736.   def execute_is_list(self, exec_ctx):
  1737.     is_number = isinstance(exec_ctx.symbol_table.get("value"), List)
  1738.     return RTResult().success(Number.true if is_number else Number.false)
  1739.   execute_is_list.arg_names = ["value"]
  1740.  
  1741.   def execute_is_function(self, exec_ctx):
  1742.     is_number = isinstance(exec_ctx.symbol_table.get("value"), BaseFunction)
  1743.     return RTResult().success(Number.true if is_number else Number.false)
  1744.   execute_is_function.arg_names = ["value"]
  1745.  
  1746.   def execute_append(self, exec_ctx):
  1747.     list_ = exec_ctx.symbol_table.get("list")
  1748.     value = exec_ctx.symbol_table.get("value")
  1749.  
  1750.     if not isinstance(list_, List):
  1751.       return RTResult().failure(RTError(
  1752.         self.pos_start, self.pos_end,
  1753.         "First argument must be list",
  1754.         exec_ctx
  1755.       ))
  1756.  
  1757.     list_.elements.append(value)
  1758.     return RTResult().success(Number.null)
  1759.   execute_append.arg_names = ["list", "value"]
  1760.  
  1761.   def execute_pop(self, exec_ctx):
  1762.     list_ = exec_ctx.symbol_table.get("list")
  1763.     index = exec_ctx.symbol_table.get("index")
  1764.  
  1765.     if not isinstance(list_, List):
  1766.       return RTResult().failure(RTError(
  1767.         self.pos_start, self.pos_end,
  1768.         "First argument must be list",
  1769.         exec_ctx
  1770.       ))
  1771.  
  1772.     if not isinstance(index, Number):
  1773.       return RTResult().failure(RTError(
  1774.         self.pos_start, self.pos_end,
  1775.         "Second argument must be number",
  1776.         exec_ctx
  1777.       ))
  1778.  
  1779.     try:
  1780.       element = list_.elements.pop(index.value)
  1781.     except:
  1782.       return RTResult().failure(RTError(
  1783.         self.pos_start, self.pos_end,
  1784.         'Element at this index could not be removed from list because index is out of bounds',
  1785.         exec_ctx
  1786.       ))
  1787.     return RTResult().success(element)
  1788.   execute_pop.arg_names = ["list", "index"]
  1789.  
  1790.   def execute_extend(self, exec_ctx):
  1791.     listA = exec_ctx.symbol_table.get("listA")
  1792.     listB = exec_ctx.symbol_table.get("listB")
  1793.  
  1794.     if not isinstance(listA, List):
  1795.       return RTResult().failure(RTError(
  1796.         self.pos_start, self.pos_end,
  1797.         "First argument must be list",
  1798.         exec_ctx
  1799.       ))
  1800.  
  1801.     if not isinstance(listB, List):
  1802.       return RTResult().failure(RTError(
  1803.         self.pos_start, self.pos_end,
  1804.         "Second argument must be list",
  1805.         exec_ctx
  1806.       ))
  1807.  
  1808.     listA.elements.extend(listB.elements)
  1809.     return RTResult().success(Number.null)
  1810.   execute_extend.arg_names = ["listA", "listB"]
  1811.  
  1812.   def execute_len(self, exec_ctx):
  1813.     list_ = exec_ctx.symbol_table.get("list")
  1814.  
  1815.     if not isinstance(list_, List):
  1816.       return RTResult().failure(RTError(
  1817.         self.pos_start, self.pos_end,
  1818.         "Argument must be list",
  1819.         exec_ctx
  1820.       ))
  1821.  
  1822.     return RTResult().success(Number(len(list_.elements)))
  1823.   execute_len.arg_names = ["list"]
  1824.  
  1825.   def execute_run(self, exec_ctx):
  1826.     fn = exec_ctx.symbol_table.get("fn")
  1827.  
  1828.     if not isinstance(fn, String):
  1829.       return RTResult().failure(RTError(
  1830.         self.pos_start, self.pos_end,
  1831.         "Second argument must be string",
  1832.         exec_ctx
  1833.       ))
  1834.  
  1835.     fn = fn.value
  1836.  
  1837.     try:
  1838.       with open(fn, "r") as f:
  1839.         script = f.read()
  1840.     except Exception as e:
  1841.       return RTResult().failure(RTError(
  1842.         self.pos_start, self.pos_end,
  1843.         f"Failed to load script \"{fn}\"\n" + str(e),
  1844.         exec_ctx
  1845.       ))
  1846.  
  1847.     _, error = run(fn, script)
  1848.    
  1849.     if error:
  1850.       return RTResult().failure(RTError(
  1851.         self.pos_start, self.pos_end,
  1852.         f"Failed to finish executing script \"{fn}\"\n" +
  1853.         error.as_string(),
  1854.         exec_ctx
  1855.       ))
  1856.  
  1857.     return RTResult().success(Number.null)
  1858.   execute_run.arg_names = ["fn"]
  1859.  
  1860. BuiltInFunction.print       = BuiltInFunction("print")
  1861. BuiltInFunction.print_ret   = BuiltInFunction("print_ret")
  1862. BuiltInFunction.input       = BuiltInFunction("input")
  1863. BuiltInFunction.input_int   = BuiltInFunction("input_int")
  1864. BuiltInFunction.clear       = BuiltInFunction("clear")
  1865. BuiltInFunction.is_number   = BuiltInFunction("is_number")
  1866. BuiltInFunction.is_string   = BuiltInFunction("is_string")
  1867. BuiltInFunction.is_list     = BuiltInFunction("is_list")
  1868. BuiltInFunction.is_function = BuiltInFunction("is_function")
  1869. BuiltInFunction.append      = BuiltInFunction("append")
  1870. BuiltInFunction.pop         = BuiltInFunction("pop")
  1871. BuiltInFunction.extend      = BuiltInFunction("extend")
  1872. BuiltInFunction.len                 = BuiltInFunction("len")
  1873. BuiltInFunction.run                 = BuiltInFunction("run")
  1874.  
  1875. #######################################
  1876. # CONTEXT
  1877. #######################################
  1878.  
  1879. class Context:
  1880.   def __init__(self, display_name, parent=None, parent_entry_pos=None):
  1881.     self.display_name = display_name
  1882.     self.parent = parent
  1883.     self.parent_entry_pos = parent_entry_pos
  1884.     self.symbol_table = None
  1885.  
  1886. #######################################
  1887. # SYMBOL TABLE
  1888. #######################################
  1889.  
  1890. class SymbolTable:
  1891.   def __init__(self, parent=None):
  1892.     self.symbols = {}
  1893.     self.parent = parent
  1894.  
  1895.   def get(self, name):
  1896.     value = self.symbols.get(name, None)
  1897.     if value == None and self.parent:
  1898.       return self.parent.get(name)
  1899.     return value
  1900.  
  1901.   def set(self, name, value):
  1902.     self.symbols[name] = value
  1903.  
  1904.   def remove(self, name):
  1905.     del self.symbols[name]
  1906.  
  1907. #######################################
  1908. # INTERPRETER
  1909. #######################################
  1910.  
  1911. class Interpreter:
  1912.   def visit(self, node, context):
  1913.     method_name = f'visit_{type(node).__name__}'
  1914.     method = getattr(self, method_name, self.no_visit_method)
  1915.     return method(node, context)
  1916.  
  1917.   def no_visit_method(self, node, context):
  1918.     raise Exception(f'No visit_{type(node).__name__} method defined')
  1919.  
  1920.   ###################################
  1921.  
  1922.   def visit_NumberNode(self, node, context):
  1923.     return RTResult().success(
  1924.       Number(node.tok.value).set_context(context).set_pos(node.pos_start, node.pos_end)
  1925.     )
  1926.  
  1927.   def visit_StringNode(self, node, context):
  1928.     return RTResult().success(
  1929.       String(node.tok.value).set_context(context).set_pos(node.pos_start, node.pos_end)
  1930.     )
  1931.  
  1932.   def visit_ListNode(self, node, context):
  1933.     res = RTResult()
  1934.     elements = []
  1935.  
  1936.     for element_node in node.element_nodes:
  1937.       elements.append(res.register(self.visit(element_node, context)))
  1938.       if res.should_return(): return res
  1939.  
  1940.     return res.success(
  1941.       List(elements).set_context(context).set_pos(node.pos_start, node.pos_end)
  1942.     )
  1943.  
  1944.   def visit_VarAccessNode(self, node, context):
  1945.     res = RTResult()
  1946.     var_name = node.var_name_tok.value
  1947.     value = context.symbol_table.get(var_name)
  1948.  
  1949.     if not value:
  1950.       return res.failure(RTError(
  1951.         node.pos_start, node.pos_end,
  1952.         f"'{var_name}' is not defined",
  1953.         context
  1954.       ))
  1955.  
  1956.     value = value.copy().set_pos(node.pos_start, node.pos_end).set_context(context)
  1957.     return res.success(value)
  1958.  
  1959.   def visit_VarAssignNode(self, node, context):
  1960.     res = RTResult()
  1961.     var_name = node.var_name_tok.value
  1962.     value = res.register(self.visit(node.value_node, context))
  1963.     if res.should_return(): return res
  1964.  
  1965.     context.symbol_table.set(var_name, value)
  1966.     return res.success(value)
  1967.  
  1968.   def visit_BinOpNode(self, node, context):
  1969.     res = RTResult()
  1970.     left = res.register(self.visit(node.left_node, context))
  1971.     if res.should_return(): return res
  1972.     right = res.register(self.visit(node.right_node, context))
  1973.     if res.should_return(): return res
  1974.  
  1975.     if node.op_tok.type == TT_PLUS:
  1976.       result, error = left.added_to(right)
  1977.     elif node.op_tok.type == TT_MINUS:
  1978.       result, error = left.subbed_by(right)
  1979.     elif node.op_tok.type == TT_MUL:
  1980.       result, error = left.multed_by(right)
  1981.     elif node.op_tok.type == TT_DIV:
  1982.       result, error = left.dived_by(right)
  1983.     elif node.op_tok.type == TT_POW:
  1984.       result, error = left.powed_by(right)
  1985.     elif node.op_tok.type == TT_EE:
  1986.       result, error = left.get_comparison_eq(right)
  1987.     elif node.op_tok.type == TT_NE:
  1988.       result, error = left.get_comparison_ne(right)
  1989.     elif node.op_tok.type == TT_LT:
  1990.       result, error = left.get_comparison_lt(right)
  1991.     elif node.op_tok.type == TT_GT:
  1992.       result, error = left.get_comparison_gt(right)
  1993.     elif node.op_tok.type == TT_LTE:
  1994.       result, error = left.get_comparison_lte(right)
  1995.     elif node.op_tok.type == TT_GTE:
  1996.       result, error = left.get_comparison_gte(right)
  1997.     elif node.op_tok.matches(TT_KEYWORD, 'and'):
  1998.       result, error = left.anded_by(right)
  1999.     elif node.op_tok.matches(TT_KEYWORD, 'or'):
  2000.       result, error = left.ored_by(right)
  2001.  
  2002.     if error:
  2003.       return res.failure(error)
  2004.     else:
  2005.       return res.success(result.set_pos(node.pos_start, node.pos_end))
  2006.  
  2007.   def visit_UnaryOpNode(self, node, context):
  2008.     res = RTResult()
  2009.     number = res.register(self.visit(node.node, context))
  2010.     if res.should_return(): return res
  2011.  
  2012.     error = None
  2013.  
  2014.     if node.op_tok.type == TT_MINUS:
  2015.       number, error = number.multed_by(Number(-1))
  2016.     elif node.op_tok.matches(TT_KEYWORD, 'not'):
  2017.       number, error = number.notted()
  2018.  
  2019.     if error:
  2020.       return res.failure(error)
  2021.     else:
  2022.       return res.success(number.set_pos(node.pos_start, node.pos_end))
  2023.  
  2024.   def visit_IfNode(self, node, context):
  2025.     res = RTResult()
  2026.  
  2027.     for condition, expr, should_return_null in node.cases:
  2028.       condition_value = res.register(self.visit(condition, context))
  2029.       if res.should_return(): return res
  2030.  
  2031.       if condition_value.is_true():
  2032.         expr_value = res.register(self.visit(expr, context))
  2033.         if res.should_return(): return res
  2034.         return res.success(Number.null if should_return_null else expr_value)
  2035.  
  2036.     if node.else_case:
  2037.       expr, should_return_null = node.else_case
  2038.       expr_value = res.register(self.visit(expr, context))
  2039.       if res.should_return(): return res
  2040.       return res.success(Number.null if should_return_null else expr_value)
  2041.  
  2042.     return res.success(Number.null)
  2043.  
  2044.   def visit_ForNode(self, node, context):
  2045.     res = RTResult()
  2046.     elements = []
  2047.  
  2048.     start_value = res.register(self.visit(node.start_value_node, context))
  2049.     if res.should_return(): return res
  2050.  
  2051.     end_value = res.register(self.visit(node.end_value_node, context))
  2052.     if res.should_return(): return res
  2053.  
  2054.     if node.step_value_node:
  2055.       step_value = res.register(self.visit(node.step_value_node, context))
  2056.       if res.should_return(): return res
  2057.     else:
  2058.       step_value = Number(1)
  2059.  
  2060.     i = start_value.value
  2061.  
  2062.     if step_value.value >= 0:
  2063.       condition = lambda: i < end_value.value
  2064.     else:
  2065.       condition = lambda: i > end_value.value
  2066.    
  2067.     while condition():
  2068.       context.symbol_table.set(node.var_name_tok.value, Number(i))
  2069.       i += step_value.value
  2070.  
  2071.       value = res.register(self.visit(node.body_node, context))
  2072.       if res.should_return() and res.loop_should_continue == False and res.loop_should_break == False: return res
  2073.      
  2074.       if res.loop_should_continue:
  2075.         continue
  2076.      
  2077.       if res.loop_should_break:
  2078.         break
  2079.  
  2080.       elements.append(value)
  2081.  
  2082.     return res.success(
  2083.       Number.null if node.should_return_null else
  2084.       List(elements).set_context(context).set_pos(node.pos_start, node.pos_end)
  2085.     )
  2086.  
  2087.   def visit_WhileNode(self, node, context):
  2088.     res = RTResult()
  2089.     elements = []
  2090.  
  2091.     while True:
  2092.       condition = res.register(self.visit(node.condition_node, context))
  2093.       if res.should_return(): return res
  2094.  
  2095.       if not condition.is_true():
  2096.         break
  2097.  
  2098.       value = res.register(self.visit(node.body_node, context))
  2099.       if res.should_return() and res.loop_should_continue == False and res.loop_should_break == False: return res
  2100.  
  2101.       if res.loop_should_continue:
  2102.         continue
  2103.      
  2104.       if res.loop_should_break:
  2105.         break
  2106.  
  2107.       elements.append(value)
  2108.  
  2109.     return res.success(
  2110.       Number.null if node.should_return_null else
  2111.       List(elements).set_context(context).set_pos(node.pos_start, node.pos_end)
  2112.     )
  2113.  
  2114.   def visit_FuncDefNode(self, node, context):
  2115.     res = RTResult()
  2116.  
  2117.     func_name = node.var_name_tok.value if node.var_name_tok else None
  2118.     body_node = node.body_node
  2119.     arg_names = [arg_name.value for arg_name in node.arg_name_toks]
  2120.     func_value = Function(func_name, body_node, arg_names, node.should_auto_return).set_context(context).set_pos(node.pos_start, node.pos_end)
  2121.    
  2122.     if node.var_name_tok:
  2123.       context.symbol_table.set(func_name, func_value)
  2124.  
  2125.     return res.success(func_value)
  2126.  
  2127.   def visit_CallNode(self, node, context):
  2128.     res = RTResult()
  2129.     args = []
  2130.  
  2131.     value_to_call = res.register(self.visit(node.node_to_call, context))
  2132.     if res.should_return(): return res
  2133.     value_to_call = value_to_call.copy().set_pos(node.pos_start, node.pos_end)
  2134.  
  2135.     for arg_node in node.arg_nodes:
  2136.       args.append(res.register(self.visit(arg_node, context)))
  2137.       if res.should_return(): return res
  2138.  
  2139.     return_value = res.register(value_to_call.execute(args))
  2140.     if res.should_return(): return res
  2141.     return_value = return_value.copy().set_pos(node.pos_start, node.pos_end).set_context(context)
  2142.     return res.success(return_value)
  2143.  
  2144.   def visit_ReturnNode(self, node, context):
  2145.     res = RTResult()
  2146.  
  2147.     if node.node_to_return:
  2148.       value = res.register(self.visit(node.node_to_return, context))
  2149.       if res.should_return(): return res
  2150.     else:
  2151.       value = Number.null
  2152.    
  2153.     return res.success_return(value)
  2154.  
  2155.   def visit_ContinueNode(self, node, context):
  2156.     return RTResult().success_continue()
  2157.  
  2158.   def visit_BreakNode(self, node, context):
  2159.     return RTResult().success_break()
  2160.  
  2161. #######################################
  2162. # RUN
  2163. #######################################
  2164.  
  2165. global_symbol_table = SymbolTable()
  2166. global_symbol_table.set("nil", Number.null)
  2167. global_symbol_table.set("false", Number.false)
  2168. global_symbol_table.set("true", Number.true)
  2169. global_symbol_table.set("math_pi", Number.math_PI)
  2170. global_symbol_table.set("print", BuiltInFunction.print)
  2171. global_symbol_table.set("print_ret", BuiltInFunction.print_ret)
  2172. global_symbol_table.set("input", BuiltInFunction.input)
  2173. global_symbol_table.set("input_int", BuiltInFunction.input_int)
  2174. global_symbol_table.set("clear", BuiltInFunction.clear)
  2175. global_symbol_table.set("cls", BuiltInFunction.clear)
  2176. global_symbol_table.set("is_num", BuiltInFunction.is_number)
  2177. global_symbol_table.set("is_str", BuiltInFunction.is_string)
  2178. global_symbol_table.set("is_list", BuiltInFunction.is_list)
  2179. global_symbol_table.set("is_func", BuiltInFunction.is_function)
  2180. global_symbol_table.set("append", BuiltInFunction.append)
  2181. global_symbol_table.set("pop", BuiltInFunction.pop)
  2182. global_symbol_table.set("extend", BuiltInFunction.extend)
  2183. global_symbol_table.set("len", BuiltInFunction.len)
  2184. global_symbol_table.set("run", BuiltInFunction.run)
  2185.  
  2186. def run(fn, text):
  2187.   # Generate tokens
  2188.   lexer = Lexer(fn, text)
  2189.   tokens, error = lexer.make_tokens()
  2190.   if error: return None, error
  2191.  
  2192.   # Generate AST
  2193.   parser = Parser(tokens)
  2194.   ast = parser.parse()
  2195.   if ast.error: return None, ast.error
  2196.  
  2197.   # Run program
  2198.   interpreter = Interpreter()
  2199.   context = Context('<program>')
  2200.   context.symbol_table = global_symbol_table
  2201.   result = interpreter.visit(ast.node, context)
  2202.  
  2203.   return result.value, result.error
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement