Example #1
0
 def parse_atom(self, tree):
   if tree.children[0] == 'type':
     tok = tree.children[1]
     args = tree.children[2]
     if args is None:
       args = []
     else:
       args = [self.parse_atom(a) for a in args.children]
     if tok.value in BasicTypes:
         t = BasicTypes[tok.value]
         if t.kind_arity != len(args):
           msg = i18n.i18n('type "%s" expects %u parameters, but receives %u') % (
                     tok.value, t.kind_arity, len(args))
           area = common.position.ProgramAreaNear(tok)
           raise GbsTypeSyntaxException(msg, area)
         return t(*args)
     else:
         if tok.value in self.context.keys():
             return self.context[tok.value]
         else:
             """[TODO] Translate """
             msg = i18n.i18n('Undefined type "%s".') % (tok.value,)
             area = common.position.ProgramAreaNear(tok)
             raise GbsTypeSyntaxException(msg, area)
   elif tree.children[0] == 'typeVar':
     tok = tree.children[1]
     if tok.value in self.typevars:
       return self.typevars[tok.value]
     else:
       fresh = GbsTypeVar(tok.value)
       self.typevars[tok.value] = fresh
       return fresh
Example #2
0
  def load(self, board, f):
    contents = f.read()
    sizes = list(re.findall('\\GbstnTamanho{([0-9]+)}{([0-9]+)}', contents))
    if len(sizes) != 1:
      raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed tex board'))
    width, height = board.size = int(sizes[0][0]), int(sizes[0][1])
    board.head = (0, 0)
    board._clear_board()
    for coli in range(4):
      col = lang.gbs_builtins.Color(coli).name()
      col_stones = re.findall('\\Gbstn' + col + '{([0-9]+)}{([0-9]+)}{([0-9]+)}' % (), contents)
      for x, y, count in col_stones:
        x, y, count = int(x), int(y), int(count)
        if x >= width or y >= height:
          raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed tex board'))
        board.cells[y][x].set_num_stones(coli, count)
    headers = list(re.findall('\\GbstnCabezal{([0-9]+)}{([0-9]+)}', contents))
    if len(headers) > 1:
      raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed tex board'))
    elif len(headers) == 1:
      x, y = int(headers[0][0]), int(headers[0][1])
      if x >= width or y >= height:
        raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed tex board'))

      board.head = y, x
    board.clear_changelog()
Example #3
0
 def start(self, filename, program_text, initial_board_string, run_mode):
     board = tools.board_format.from_string(initial_board_string)
     
     if run_mode == XGobstonesWorker.RunMode.ONLY_CHECK:
         options = lang.GobstonesOptions()
     else:
         options = lang.GobstonesOptions()
     self.gobstones = lang.Gobstones(options, self.api)
     
     try:
         if run_mode == XGobstonesWorker.RunMode.FULL:
             self.success(self.gobstones.run(filename, program_text, board))
         else:
             # Parse gobstones script
             self.gobstones.api.log(i18n.i18n('Parsing.'))
             tree = self.gobstones.parse(program_text, filename)            
             assert tree
             # Explode macros
             self.gobstones.api.log(i18n.i18n('Exploding program macros.'))            
             self.gobstones.explode_macros(tree)
             # Check semantics, liveness and types
             self.gobstones.check(tree)
             self.success()
     except Exception as exception:
         self.failure(exception)
Example #4
0
 def parse_atom(self, tree):
     if tree.children[0] == 'typeNameTypeCall':
         tok = tree.children[1]
         args = tree.children[2]
         if args is None:
             args = []
         else:
             args = [self.parse_atom(a) for a in args.children]
         if tok.value not in BasicTypes:
             msg = i18n.i18n('"%s" is not a basic type') % (tok.value, )
             area = common.position.ProgramAreaNear(tok)
             raise GbsTypeSyntaxException(msg, area)
         t = BasicTypes[tok.value]
         if t.kind_arity != len(args):
             msg = i18n.i18n(
                 'type "%s" expects %u parameters, but receives %u') % (
                     tok.value, t.kind_arity, len(args))
             area = common.position.ProgramAreaNear(tok)
             raise GbsTypeSyntaxException(msg, area)
         return t(*args)
     elif tree.children[0] == 'typeVar':
         tok = tree.children[1]
         if tok.value in self.typevars:
             return self.typevars[tok.value]
         else:
             fresh = GbsTypeVar(tok.value)
             self.typevars[tok.value] = fresh
             return fresh
Example #5
0
 def init_tags(self):
   self.reserved = {
     'delim': [
       '{', '}', '(', ')', ';', ',',
     ],
     'Main': ['Main'],
     'keyword': [
       'if', 'else', 'not', 'switch', 'to', 'while',
       'foreach', 'in', 'procedure', 'function',
       'return', 'div', 'mod', 'Skip',
       'from', 'import',
     ],
     'builtin_procedure': [i18n.i18n(name) for name in [
       'THROW_ERROR', 'PutStone', 'TakeStone', 'Move', 'GoToOrigin', 'ClearBoard',
     ]],
     'builtin_function': [i18n.i18n(name) for name in [
       'numStones', 'existStones', 'canMove', 'minBool', 'maxBool',
       'minDir', 'maxDir', 'minColor', 'maxColor', 'next', 'prev',
       'opposite',
     ]],
     'builtin_constant': [i18n.i18n(name) for name in [
       'True', 'False', 'North', 'South', 'East', 'West',
       'Color0', 'Color1', 'Color2', 'Color3',
     ]],
     'type': [i18n.i18n(name) for name in [
       'Color', 'Dir', 'Int', 'Bool',
     ]],
   }
   self.tags = TAGS
   for tag, (fg, bg) in self.tags.items():
     if fg is not None:
       self.tag_config(tag, foreground=fg)
     if bg is not None:
       self.tag_config(tag, background=bg)
Example #6
0
 def parse_atom(self, tree):
     if tree.children[0] == 'type':
         tok = tree.children[1]
         args = tree.children[2]
         if args is None:
             args = []
         else:
             args = [self.parse_atom(a) for a in args.children]
         if tok.value in BasicTypes:
             t = BasicTypes[tok.value]
             if t.kind_arity != len(args):
                 msg = i18n.i18n(
                     'type "%s" expects %u parameters, but receives %u') % (
                         tok.value, t.kind_arity, len(args))
                 area = common.position.ProgramAreaNear(tok)
                 raise GbsTypeSyntaxException(msg, area)
             return t(*args)
         else:
             if tok.value in self.context.keys():
                 return self.context[tok.value]
             else:
                 """[TODO] Translate """
                 msg = i18n.i18n('Undefined type "%s".') % (tok.value, )
                 area = common.position.ProgramAreaNear(tok)
                 raise GbsTypeSyntaxException(msg, area)
     elif tree.children[0] == 'typeVar':
         tok = tree.children[1]
         if tok.value in self.typevars:
             return self.typevars[tok.value]
         else:
             fresh = GbsTypeVar(tok.value)
             self.typevars[tok.value] = fresh
             return fresh
Example #7
0
 def compile_foreach_sequence(self, tree, code):
     "Compile a foreach's sequence."
     sequence = tree.children[2].children[1:]
     code.push(('call', i18n.i18n('[]'), 0), near=tree)
     for element in sequence:
         self.compile_expression(element, code)
         code.push(('call', i18n.i18n('_snoc'), 2), near=tree)
Example #8
0
 def parse_atom(self, tree):
   if tree.children[0] == 'typeNameTypeCall':
     tok = tree.children[1]
     args = tree.children[2]
     if args is None:
       args = []
     else:
       args = [self.parse_atom(a) for a in args.children]
     if tok.value not in BasicTypes:
       msg = i18n.i18n('"%s" is not a basic type') % (tok.value,)
       area = common.position.ProgramAreaNear(tok)
       raise GbsTypeSyntaxException(msg, area)
     t = BasicTypes[tok.value]
     if t.kind_arity != len(args):
       msg = i18n.i18n('type "%s" expects %u parameters, but receives %u') % (
                 tok.value, t.kind_arity, len(args))
       area = common.position.ProgramAreaNear(tok)
       raise GbsTypeSyntaxException(msg, area)
     return t(*args)
   elif tree.children[0] == 'typeVar':
     tok = tree.children[1]
     if tok.value in self.typevars:
       return self.typevars[tok.value]
     else:
       fresh = GbsTypeVar(tok.value)
       self.typevars[tok.value] = fresh
       return fresh
Example #9
0
    def start_test_case(self, i):
        if i >= len(self._test_cases):
            self.log(i18n.i18n('Program execution finished.'))
            self._state = 'end'
            return 'END'
        n_of_m = ' (%s/%s)' % ((i + 1), len(self._test_cases))
        self.log(
            i18n.i18n('Starting test case %s.') %
            (self._test_cases[i].id(), ) + n_of_m)

        compiled_code = self._code_dict.compiled_code_for(
            self._test_cases[i].program_name())
        self._test_board = self._bundle.load_board(
            self._problem, self._test_cases[i].board_name())

        try:
            self._vm = lang.gbs_vm.GbsVmInterpreter(
                toplevel_filename=self._code_dict._solution_filename)
            self._vm.init_program(compiled_code, self._test_board)
        except common.utils.SourceException as exception:
            self._error_exception = exception
            self._state = 'failed'
            return 'FAILED'
        self._state = 'running'
        return 'CONTINUE'
Example #10
0
    def board_change_size(self, *args):
        if self.tools.DefaultBoardSize == 'random':
            w, h = 9, 9
        else:
            w, h = self.tools.DefaultBoardSize

        # ask for size
        msg = i18n.i18n('Invalid board size')
        nw = tkinter.simpledialog.askstring(
                      i18n.i18n('Change board size'),
                      i18n.i18n('Width:'),
                      initialvalue='%s' % (w,))
        nh = tkinter.simpledialog.askstring(
                      i18n.i18n('Change board size'),
                      i18n.i18n('Height:'),
                      initialvalue='%s' % (h,))

        if not common.utils.is_int(nw) or not common.utils.is_int(nh):
            return self.show_string_error(msg)
        w, h = int(nw), int(nh)
        if w == 0 or h == 0 or w > 200 or h > 200:
            return self.show_string_error(msg)

        self.tools.DefaultBoardSize = w, h
        # resize board
        if not self.viewer:
            self.open_viewer()
        self.viewer.randomize()
        self.viewer.show_board0()
Example #11
0
 def start(self, filename, program_text, initial_board_string, run_mode):
     board = tools.board_format.from_string(initial_board_string)
             
     if run_mode == Interpreter.RunMode.ONLY_CHECK:
         options = lang.GobstonesOptions("lax", True, True)
     else:
         options = lang.GobstonesOptions()
     self.gobstones = lang.Gobstones(options, self.api)
     
     try:
         if run_mode == Interpreter.RunMode.FULL:
             self.success(self.gobstones.run(filename, program_text, board))
         else:
             # Parse gobstones script
             self.gobstones.api.log(i18n.i18n('Parsing.'))
             tree = self.gobstones.parse(program_text, filename)            
             assert tree
             # Explode macros
             self.gobstones.api.log(i18n.i18n('Exploding program macros.'))            
             self.gobstones.explode_macros(tree)
             # Check semantics, liveness and types
             self.gobstones.check(tree)
             self.success()
     except Exception as exception:
         self.failure(exception)
Example #12
0
    def load(self, board, f):
        contents = f.read()
        sizes = list(re.findall('\\GbstnTamanho{([0-9]+)}{([0-9]+)}',
                                contents))
        if len(sizes) != 1:
            raise lang.board.basic.BoardFormatException(
                i18n.i18n('Malformed tex board'))
        width, height = board.size = int(sizes[0][0]), int(sizes[0][1])
        board.head = (0, 0)
        board._clear_board()
        for coli in range(4):
            col = lang.gbs_builtins.Color(coli).name()
            col_stones = re.findall(
                '\\Gbstn' + col + '{([0-9]+)}{([0-9]+)}{([0-9]+)}' % (),
                contents)
            for x, y, count in col_stones:
                x, y, count = int(x), int(y), int(count)
                if x >= width or y >= height:
                    raise lang.board.basic.BoardFormatException(
                        i18n.i18n('Malformed tex board'))
                board.cells[y][x].set_num_stones(coli, count)
        headers = list(
            re.findall('\\GbstnCabezal{([0-9]+)}{([0-9]+)}', contents))
        if len(headers) > 1:
            raise lang.board.basic.BoardFormatException(
                i18n.i18n('Malformed tex board'))
        elif len(headers) == 1:
            x, y = int(headers[0][0]), int(headers[0][1])
            if x >= width or y >= height:
                raise lang.board.basic.BoardFormatException(
                    i18n.i18n('Malformed tex board'))

            board.head = y, x
        board.clear_changelog()
Example #13
0
    def _infer_func_call(self, tree, nretvals):
        "Infer types for a function call."
        fun_name = tree.children[1].value
        fun_type = self.global_context[fun_name].instantiate()
        arg_type = self.infer_tuple(tree.children[2])
        subtypes = [lang.gbs_type.GbsTypeVar() for i in range(nretvals)]
        res_type = lang.gbs_type.GbsTupleType(subtypes)
        expected = lang.gbs_type.GbsFunctionType(arg_type, res_type)

        # check parameters
        try:
            lang.gbs_type.unify(fun_type.paramtype(), expected.paramtype())
        except lang.gbs_type.UnificationFailedException as e:
            area = common.position.ProgramAreaNear(tree)
            msg = i18n.i18n('function "%s" is receiving: %s\n' +
                            'But should receive: %s') % (fun_name,
                                                         expected.paramtype(),
                                                         fun_type.paramtype())
            raise GbsTypeInferenceException(msg, area)

        # check return value
        try:
            lang.gbs_type.unify(fun_type._res, expected._res)
        except lang.gbs_type.UnificationFailedException as e:
            area = common.position.ProgramAreaNear(tree)
            msg = i18n.i18n('function "%s" is called as if it returned: %s\n' +
                            'But returns: %s') % (fun_name, expected._res,
                                                  fun_type._res)
            raise GbsTypeInferenceException(msg, area)

        tree.type_annotation = expected.parameters()
        return res_type
Example #14
0
 def init_tags(self):
   self.reserved = {
     'delim': [
       '{', '}', '(', ')', ';', ',',
     ],      
     'keyword': [
       'if', 'else', 'not', 'case', 'while', 'switch', 'to', 'match', 
       'field', 'record', 'is', 'variant', 'type',
       'repeat', 'foreach', 'in', 'procedure', 'function',
       'return', 'div', 'mod', 'Skip',
       'from', 'import', 'program', 'interactive'
     ],
     'builtin_procedure': [i18n.i18n(name) for name in [
       'THROW_ERROR', 'PutStone', 'TakeStone', 'Move', 'GoToOrigin', 'ClearBoard',
     ]],
     'builtin_function': [i18n.i18n(name) for name in [
       'numStones', 'existStones', 'canMove', 'minBool', 'maxBool',
       'minDir', 'maxDir', 'minColor', 'maxColor', 'next', 'prev',
       'opposite',
     ]],
     'builtin_constant': [i18n.i18n(name) for name in [
       'True', 'False', 'North', 'South', 'East', 'West',
       'Color0', 'Color1', 'Color2', 'Color3',
     ]],
     'type': [i18n.i18n(name) for name in [
       'Color', 'Dir', 'Int', 'Bool',
     ]],
   }
   self.tags = TAGS
   for tag, (fg, bg) in self.tags.items():
     if fg is not None:
       self.tag_config(tag, foreground=fg)
     if bg is not None:
       self.tag_config(tag, background=bg)
Example #15
0
    def check_import(self, tree):
        mdl_name = tree.children[1].value
        if not self.module_handler.module_exists(mdl_name):
            pos = common.position.ProgramAreaNear(tree.children[1])
            raise GbsLintException(i18n.i18n('Module %s cannot be found') % (mdl_name,), pos)

        try:
            mdl_tree = self.module_handler.parse_tree(mdl_name)
        except common.utils.SourceException as exception:
            self.module_handler.reraise(GbsLintException, exception,
                                                      common.i18n.i18n('Error parsing module %s') % (mdl_name,),
                                                      common.position.ProgramAreaNear(tree.children[1]))

        if mdl_name in self.loaded_modules:
            pos = common.position.ProgramAreaNear(tree.children[1])
            raise GbsLintException(i18n.i18n('Recursive modules'), pos)

        mdl_lint = GbsSemanticChecker(strictness=self.strictness, warn=self.warn, explicit_board=self.explicit_board)        
        try:
            mdl_lint.check_program(mdl_tree, self.loaded_modules + [mdl_name], is_main_program=False)
        except common.utils.SourceException as exception:
            self.module_handler.reraise(GbsLintException, exception,
                                                      common.i18n.i18n('Error linting module %s') % (mdl_name,),
                                                      common.position.ProgramAreaNear(tree.children[1]))

        import_tokens = tree.children[2].children
        imports = map(lambda imp: imp.value, import_tokens)
        
        constructs = tree.children[2].children = mdl_lint.all_defined_routine_or_type_names()
                
        if not (len(imports) == 1 and imports[0] == '*'):
            newcons = []
            imported = []
            for construct in constructs:
                if construct.name() in imports:
                    newcons.append(construct)
                    imported.append(construct.name())
                    if isinstance(construct, lang.gbs_constructs.UserType):
                        newcons.extend(mdl_lint.field_getters_for_type(construct.name()))
            constructs = newcons
            invalid_imports = set(imports).difference(set(imported))
            if len(invalid_imports) > 0:
                import_index = imports.index(invalid_imports[0])
                mdl_lint.symbol_table._error_not_defined(import_tokens[import_index], 
                                                         imports[import_index], 
                                                         'type or callable')
                                
        for construct in constructs:
            if isinstance(construct, lang.gbs_constructs.BuiltinFieldGetter):
                if not construct.name() in self.imported_rtns: 
                    self.symbol_table.add(construct, area=None)
                    self.imported_rtns[construct.name()] = True
            else:
                if construct.name() in self.imported_rtns:
                    pos = common.position.ProgramAreaNear(construct.identifier())
                    raise GbsLintException(i18n.i18n('%s %%s was already imported' % (construct.type(),)) % (construct.name(),), pos)    
                else:
                    self.symbol_table.add(construct, area=common.position.ProgramAreaNear(construct.identifier()))
                    self.imported_rtns[construct.name()] = True
Example #16
0
 def check(self, options):
     if options['src']:
         self.check_file_exists(options['src'])
     if options['from']:
         self.check_file_exists(options['from'])
     if options['lint'] not in lang.GobstonesOptions.LINT_MODES:
         raise OptionsException(i18n.i18n('%s is not a valid lint option.') % (options['lint'],))
     if not self.check_size(options['size']):
         raise OptionsException(i18n.i18n('Size %s is not a valid size. Positive integers expected.') % (str(options['size']),))
Example #17
0
    def __init__(self, tools, parent_gui=None, font=gui.config.DefaultFont, *args, **kwargs):
        tkinter.Tk.__init__(self, *args, **kwargs)
        self.tools = tools
        self.parent_gui = parent_gui
        self._font = font

        bframe = tkinter.Frame(self)
        ti = i18n.i18n('Initial board')
        tf = i18n.i18n('Final board')
        self.button0 = tkinter.Button(bframe, text=ti, command=self.show_board0)
        self.button1 = tkinter.Button(bframe, text=tf, command=self.show_board1)
        self.button0.pack(side=tkinter.LEFT)
        self.button1.pack(side=tkinter.LEFT)

        self.bind_all('<KeyPress>', self.keypress)
        self.bind_all('<z>', self.board_zoom_out)
        self.bind_all('<x>', self.board_zoom_in)
        self.bind_all('<KeyPress-Up>',
            lambda ev: self.keypress_cursor(self.tools.builtins.NORTH, ev))
        self.bind_all('<KeyPress-Down>',
            lambda ev: self.keypress_cursor(self.tools.builtins.SOUTH, ev))
        self.bind_all('<KeyPress-Left>',
            lambda ev: self.keypress_cursor(self.tools.builtins.WEST, ev))
        self.bind_all('<KeyPress-Right>',
            lambda ev: self.keypress_cursor(self.tools.builtins.EAST, ev))
        self.bind_all('<Home>', lambda ev: self.grandmove('home'))
        self.bind_all('<End>', lambda ev: self.grandmove('end'))
        self.bind_all('<Prior>', lambda ev: self.grandmove('up'))
        self.bind_all('<Next>', lambda ev: self.grandmove('down'))
        bframe.pack(side=tkinter.TOP, fill=tkinter.X)

        self.board0 = self.tools.Board((1, 1))
        self.board0.randomize_full()

        self.board1 = self.tools.Board((1, 1))
        self.reset_board1()

        self._build_scrolled_board_frame()
        self.err_frame = None

        self.show_board0()
        self.visible_board = None

        self.filename = None

        if self.parent_gui:
            self.bind_all('<Control-e>', self.parent_gui.board_empty)
            self.bind_all('<Control-i>', lambda *args: self.parent_gui.board_random_full())
            self.bind_all('<Control-r>', lambda *args: self.parent_gui.board_random_contents())
            self.bind_all('<Control-t>', self.parent_gui.board_change_size)
            self.bind_all('<Control-b>', lambda *args: self.parent_gui.board_load())
            self.bind_all('<Control-g>', lambda *args: self.parent_gui.board_save())
            self.bind_all('<Control-n>', self.parent_gui.file_new)
            self.bind_all('<Control-o>', self.parent_gui.file_open)
            self.bind_all('<Control-s>', self.parent_gui.file_save)
            self.bind_all('<F5>', self.parent_gui.gobstones_start_run)
            self.bind_all('<F10>', self.parent_gui.gobstones_check)
Example #18
0
 def _warn_conflict(self, nonterminal, terminal, area):
     "Emits a warning for a conflictive state."
     msg = ''
     msg += i18n.i18n('Conflictive rule for: ("%s", "%s")\n') % (
         nonterminal, terminal)
     msg += i18n.i18n('Will choose first production:\n')
     msg += common.utils.indent(
         bnf_rule_to_str(self._parse_table[(nonterminal, terminal)]))
     self.warn(ParserException(msg, area))
Example #19
0
 def _warn_conflict(self, nonterminal, terminal, area):
     "Emits a warning for a conflictive state."
     msg = ''
     msg += i18n.i18n('Conflictive rule for: ("%s", "%s")\n') % (
                 nonterminal, terminal)
     msg += i18n.i18n('Will choose first production:\n')
     msg += common.utils.indent(bnf_rule_to_str(
                     self._parse_table[(nonterminal, terminal)]))
     self.warn(ParserException(msg, area))
Example #20
0
 def check(self, options):
     if options['src']:
         self.check_file_exists(options['src'])
     if options['from']:
         self.check_file_exists(options['from'])
     if options['lint'] not in lang.GobstonesOptions.LINT_MODES:
         raise OptionsException(i18n.i18n('%s is not a valid lint option.') % (options['lint'],))
     if not self.check_size(options['size']):
         raise OptionsException(i18n.i18n('Size %s is not a valid size. Positive integers expected.') % (str(options['size']),))
Example #21
0
 def parse(self, filename, program_text):
     # Parse gobstones script
     self.api.log(i18n.i18n('Parsing.'))
     tree = self._parse(program_text, filename)
     assert tree
     # Explode macros
     self.api.log(i18n.i18n('Exploding program macros.'))
     self.explode_macros(tree)
     return GobstonesRun().initialize(tree)
Example #22
0
 def _file_close(self):
     if self.editor.text_has_changed():
         ans = tkinter.messagebox.askyesnocancel(
             i18n.i18n('File not saved'),
             i18n.i18n('File has not been saved.\nSave it now?'))
         if ans is None: return False
         if ans == True:
             if not self.file_save(): return False
     self.editor.new_file()    
     return True
Example #23
0
 def draw_stone(self, x0, y0, x1, y1, col, count):
     if count == 0: return
     sm = (x1 - x0) // 8
     fill = i18n.i18n(Colors['stone_fill%i' % (col,)])
     outline = i18n.i18n(Colors['stone_border%i' % (col,)])
     self.create_oval(x0 + sm, y0 + sm, x1 - sm, y1 - sm,
                                       outline=outline, fill=fill, width=1)
     self.create_text((x0 + x1) // 2, (y0 + y1) // 2,
                                       font=self._font,
                                       text=str(count), justify=tkinter.CENTER)
Example #24
0
 def _init_filetypes(self):
     self.filetypes = {
         'gbs': [
             (i18n.i18n('Gobstones source'), '*.gbs', 'TEXT'),
             (i18n.i18n('All files'), '*'),
         ],
     }
     self.filetypes['board_load'] = [
             (i18n.i18n('Gobstones board'), '*.gbb', 'TEXT'),
             (i18n.i18n('Gobstones board (old format)'), '*.gbt', 'TEXT'),
             (i18n.i18n('TeX/LaTeX file'), '*.tex', 'TEXT'),
     ]
     self.filetypes['board_save'] = self.filetypes['board_load'][:]
     self.filetypes['board_save'].append(
             (i18n.i18n('HTML file'), '*.html', 'TEXT')
     )
     self.filetypes['board_save'].append(
             (i18n.i18n('FIG image file'), '*.fig', 'TEXT')
     )
     self.filetypes['board_load'].append(
             (i18n.i18n('All files'), '*'),
     )
     self.filetypes['board_save'].append(
             (i18n.i18n('All files'), '*'),
     )
def board_move(global_state, direction):
    """Move the head."""
    if poly_typeof(direction) != 'Dir':
        msg = i18n.i18n('The argument to Move should be a direction')
        raise GbsRuntimeException(msg, global_state.area())
    if global_state.board.can_move(direction):
        global_state.board.move(direction)
    else:
        msg = global_state.backtrace(
            i18n.i18n('Cannot move to %s') % (direction,))
        raise GbsRuntimeException(msg, global_state.area())
def board_take_stone(global_state, color):
    """Take a stone from the board."""
    if poly_typeof(color) != 'Color':
        msg = i18n.i18n('The argument to TakeStone should be a color')
        raise GbsRuntimeException(msg, global_state.area())
    if global_state.board.num_stones(color) > 0:
        global_state.board.take_stone(color)
    else:
        msg = global_state.backtrace(
            i18n.i18n('Cannot take stones of color %s') % (color,))
        raise GbsRuntimeException(msg, global_state.area())
Example #27
0
def board_take_stone(global_state, color):
    """Take a stone from the board."""
    if poly_typeof(color) != 'Color':
        msg = i18n.i18n('The argument to TakeStone should be a color')
        raise GbsRuntimeException(msg, global_state.area())
    if global_state.board.num_stones(color) > 0:
        global_state.board.take_stone(color)
    else:
        msg = global_state.backtrace(
            i18n.i18n('Cannot take stones of color %s') % (color, ))
        raise GbsRuntimeException(msg, global_state.area())
Example #28
0
 def _set_routine_definition_type(self, tree, prfn, name, params, body):
     """Given a context with types for the parameters and local
     variables in a routine, build the type for this routine
     and unify it with its type in the global context.
     For instance if the function "f" has a parameter "x",
     and returns an expression, take the type "s" for "x"
     from the local context, the type "t" for the returned
     expression. Build the type "s -> t" for the function
     and unify that with any type information previously
     known for "f". This requires that the body of the routine
     has already been typechecked."""
     param_types = []
     for p in params.children:
         param_types.append(self.context[p.value])
     param_types = lang.gbs_type.GbsTupleType(param_types)
     if prfn == 'procedure':
         def_type = lang.gbs_type.GbsProcedureType(param_types)
     elif prfn == 'function':
         return_types = self._return_type(prfn, name, params, body)
         def_type = lang.gbs_type.GbsFunctionType(param_types, return_types)
     elif prfn == 'entrypoint' and (name.value == 'program' or name.value == 'interactive'):
         def_type = lang.gbs_type.GbsEntryPointType()
     else:
         assert False
     expected = self.global_context[name.value].instantiate()
     try:
         lang.gbs_type.unify(expected, def_type)
         if prfn == 'function': #[TODO] Check
             freevars = def_type.freevars()
             if len(freevars) > 0:
                 def_type = lang.gbs_type.GbsForallType(freevars, def_type)
                 self.global_context[name.value] = def_type
         tree.type_annot = def_type
     except lang.gbs_type.UnificationFailedException as e:
         area = common.position.ProgramAreaNear(tree)
         if prfn == 'procedure':
             msg = i18n.i18n(
                       'procedure "%s" should take: %s\n' +
                       'But takes: %s'
                   ) % (
                       name.value,
                       expected.paramtype(),
                       def_type.paramtype()
                   )
         else:
             msg = i18n.i18n(
                       'function "%s" should take: %s and return: %s\n' +
                       'But takes: %s and returns: %s'
                   ) % (
                       name.value,
                       expected.paramtype(), expected.restype(),
                       def_type.paramtype(), def_type.restype()
                   )
         self.error(GbsTypeInferenceException(msg, area))
Example #29
0
 def _error_conflictive_definition(self, tree, name, as_type, val):
     if val.name() == name:
         area = common.position.ProgramAreaNear(tree)
         l1 = i18n.i18n('"%s" is not a ' + as_type) % (name,)
         l2 = i18n.i18n(val.type() + ' "%s" defined %s') % (name, val.where())
         raise GbsLintException('\n'.join([l1, l2]), area)
     else:
         area = common.position.ProgramAreaNear(tree)
         msg = i18n.i18n('"%s" is too similar to ' + val.type() + ' "%s", defined %s') % (
                         name, val.name(), val.where())
         raise GbsLintException(msg, area)
Example #30
0
def list_binary_operation(global_state, lst1, lst2, f):
    """Wrapper for binary list operations to ensure list types"""
    if poly_typeof(lst1) == poly_typeof(lst2) and poly_typeof(lst1) == 'List' and list_inner_type_eq(lst1, lst2):
        return f(lst1, lst2)
    else:
        if poly_typeof(lst1) != 'List':
            msg = global_state.backtrace(i18n.i18n('%s was expected') % (i18n.i18n('list type value'),))
            raise GbsRuntimeException(msg, global_state.area())
        else:
            msg = global_state.backtrace(i18n.i18n('Concatenation between lists with different inner type.'))
            raise GbsRuntimeException(msg, global_state.area())
Example #31
0
 def compile_foreach_range(self, tree, code):
     "Compile a foreach's range."
     _, range_first, range_last, range_second = tree.children[2].children
     self.compile_expression(range_first, code)
     self.compile_expression(range_last, code)
     if not range_second is None:
         self.compile_expression(range_second, code)
     else:
         self.compile_expression(range_first, code)
         code.push(('call', i18n.i18n('next'), 1), near=tree)
     code.push(('call', i18n.i18n('_range'), 3), near=tree)
Example #32
0
def board_move(global_state, direction):
    """Move the head."""
    if poly_typeof(direction) != 'Dir':
        msg = i18n.i18n('The argument to Move should be a direction')
        raise GbsRuntimeException(msg, global_state.area())
    if global_state.board.can_move(direction):
        global_state.board.move(direction)
    else:
        msg = global_state.backtrace(
            i18n.i18n('Cannot move to %s') % (direction, ))
        raise GbsRuntimeException(msg, global_state.area())
Example #33
0
 def _add_index(self, varName, tree):
     var = self.symbol_table.check_not_defined_or_defined_as(tree, varName, 'atomic', ['index', 'variable', 'parameter'])
     if var is None:
         self.symbol_table.add(lang.gbs_constructs.UserIndex(varName, tree))
     elif var.type() == 'variable':
         msg = i18n.i18n('Index of a foreach/repeatWith/repeat cannot be a variable: "%s"') % (varName,)
         area = common.position.ProgramAreaNear(tree)
         raise GbsLintException(msg, area)
     elif var.type() == 'parameter':
         msg = i18n.i18n('Index of a foreach/repeatWith/repeat cannot be a parameter: "%s"') % (varName,)
         area = common.position.ProgramAreaNear(tree)
         raise GbsLintException(msg, area)
Example #34
0
 def _add_var(self, varName, tree):
     var = self.symbol_table.check_not_defined_or_defined_as(tree, varName, 'atomic', ['variable', 'index', 'parameter'])
     if var is None:
         self.symbol_table.add(lang.gbs_constructs.UserVariable(varName, tree))
     elif var.type() == 'index':
         msg = i18n.i18n('Cannot modify "%s": index of a foreach/repeatWith/repeat is immutable') % (varName,)
         area = common.position.ProgramAreaNear(tree)
         raise GbsLintException(msg, area)
     elif var.type() == 'parameter':
         msg = i18n.i18n('Cannot modify "%s": parameter is immutable') % (varName,)
         area = common.position.ProgramAreaNear(tree)
         raise GbsLintException(msg, area)
Example #35
0
 def _put_from_description(self, cell, description):
   coli = 0
   for cn in lang.gbs_builtins.COLOR_NAMES:
     if description[-1].lower() == cn[0].lower():
       count = description[:-1]
       for l in count:
         if l not in '0123456789':
           raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed board'))
       cell.put(coli, int(count))
       return
     coli += 1
   raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed board'))
Example #36
0
 def force_file_save(self, *args):
     if self.editor.has_filename():
         self.editor.save_file(self.editor.filename())
         return True
     else:
         ans = tkinter.messagebox.askyesno(
             i18n.i18n('Source must be saved'),
             i18n.i18n('Source must be saved.\nOk to save?'))
         if ans == True:
             return self.file_save_as()
         else:
             return False
Example #37
0
 def _put_from_description(self, cell, description):
   coli = 0
   for cn in lang.gbs_builtins.COLOR_NAMES:
     if description[-1].lower() == cn[0].lower():
       count = description[:-1]
       for l in count:
         if l not in '0123456789':
           raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed board'))
       cell.put(coli, int(count))
       return
     coli += 1
   raise lang.board.basic.BoardFormatException(i18n.i18n('Malformed board'))
Example #38
0
def run_filename(fn, **options):
    if not os.path.exists(fn):
        report_error(i18n.i18n('Error'),
                     i18n.i18n('File %s does not exist') % (fn, ))
        return False

    lfn = fn.lower()
    if lfn.endswith('.gbo'):
        return run_object_filename(fn, **options)
    elif lang.board.formats.is_board_filename(fn):
        return run_board_filename(fn, **options)
    else:
        return run_gbs_filename(fn, **options)
Example #39
0
 def compile(self, filename, program_text):
     gbs_run = self.parse(filename, program_text)
     tree = gbs_run.tree
     # Check semantics, liveness and types
     self.check(tree)
     # Optimize program
     if self.options.optimize:
         self.api.log(i18n.i18n('Optimizing.')) #[TODO] i18n
         lang.gbs_optimizer.optimize(tree)
     # Compile program
     self.api.log(i18n.i18n('Compiling.'))
     gbs_run.compiled_program = self.compile_program(tree)
     return gbs_run
Example #40
0
 def _error_conflictive_definition(self, tree, name, as_type, val):
     if val.name() == name:
         area = common.position.ProgramAreaNear(tree)
         l1 = i18n.i18n('"%s" is not a ' + as_type) % (name, )
         l2 = i18n.i18n(val.type() + ' "%s" defined %s') % (name,
                                                            val.where())
         raise GbsLintException('\n'.join([l1, l2]), area)
     else:
         area = common.position.ProgramAreaNear(tree)
         msg = i18n.i18n('"%s" is too similar to ' + val.type() +
                         ' "%s", defined %s') % (name, val.name(),
                                                 val.where())
         raise GbsLintException(msg, area)
Example #41
0
 def _result(self, tit, out, board, head_pos, keyvals):
   if board is not None:
     out.write('  <h3>%s</h3>\n' % (tit,))
     out.write(html_board(board, draw_head=self._options['check_head']))
   if self._options['check_result']:
     out.write('  <h3>%s</h3>\n' % (i18n.i18n('Returned variables'),))
     if len(keyvals) == 0:
       out.write('  <tt>&lt;%s&gt;</tt>\n' % (i18n.i18n('No returned variables'),))
     else:
       out.write('  <div class="returned_vars">\n')
       for k, v in keyvals:
         out.write('<p><tt>%s -&gt; %s</tt></p>\n' % (k, v))
       out.write('  </div>\n')
Example #42
0
 def parse_error(self, nonterminal, previous_token, token):
     "Raises a GbstonesParserException describing a parse error."
     area = common.position.ProgramAreaNear(token)
     if previous_token.type == 'lowerid' and token.type == '(':
         raise GbsParserException(i18n.i18n('Cannot call a function here'), area)
     elif previous_token.type == 'upperid' and token.type == '(':
         raise GbsParserException(i18n.i18n('Cannot call a procedure here'), area)
     elif previous_token.type == 'upperid' and token.type != '(':
         msg = i18n.i18n('Procedure name "%s" is missing a "("') % (previous_token.value,)
         raise GbsParserException(msg, area)
     elif token.type == 'EOF':
         raise GbsParserException(i18n.i18n('Premature end of input'), area)
     lang.bnf_parser.Parser.parse_error(self, nonterminal, previous_token, token)
Example #43
0
 def _tabmenu(self, out):
     out.write('<p>\n')
     out.write(
         '  <input type="submit" class="btn" id="link_test_case" onclick="show(\'test_case\')" value="%s">\n'
         % (i18n.i18n('Test case'), ))
     if self._options['provide_expected_result']:
         out.write(
             '  <input type="submit" class="btn" id="link_expected_result" onclick="show(\'expected_result\')" value="%s">\n'
             % (i18n.i18n('Expected result'), ))
     out.write(
         '  <input type="submit" class="btn" id="link_obtained_result" onclick="show(\'obtained_result\')" value="%s">\n'
         % (i18n.i18n('Obtained result'), ))
     out.write('</p>\n')
Example #44
0
    def check_import(self, tree):
        mdl_name = tree.children[1].value
        if not self.module_handler.module_exists(mdl_name):
            pos = common.position.ProgramAreaNear(tree.children[1])
            raise GbsLintException(i18n.i18n('Module %s cannot be found') % (mdl_name,), pos)

        try:
            mdl_tree = self.module_handler.parse_tree(mdl_name)
        except common.utils.SourceException as exception:
            self.module_handler.reraise(GbsLintException, exception,
                                                      common.i18n.i18n('Error parsing module %s') % (mdl_name,),
                                                      common.position.ProgramAreaNear(tree.children[1]))

        if mdl_name in self.loaded_modules:
            pos = common.position.ProgramAreaNear(tree.children[1])
            raise GbsLintException(i18n.i18n('Recursive modules'), pos)

        mdl_lint = GbsSemanticChecker(strictness=self.strictness, warn=self.warn)
        try:
            mdl_lint.check_program(mdl_tree, self.loaded_modules + [mdl_name], is_main_program=False)
        except common.utils.SourceException as exception:
            self.module_handler.reraise(GbsLintException, exception,
                                                      common.i18n.i18n('Error linting module %s') % (mdl_name,),
                                                      common.position.ProgramAreaNear(tree.children[1]))

        rtns = tree.children[2].children

        if len(rtns) == 1 and rtns[0].value == '*':
            rtns = tree.children[2].children = mdl_lint.all_defined_routine_or_type_names()

        for rtn in rtns:
            if rtn.type == 'lowerid':
                construct_type = 'function'
            else:
                construct_type = 'procedure'

            if mdl_lint.symbol_table.is_defined_as(rtn, rtn.value, 'callable', construct_type):
                construct = mdl_lint.symbol_table.get('callable', rtn.value, None)
            elif mdl_lint.symbol_table.is_defined_as(rtn, rtn.value, 'atomic', 'type'):
                construct_type = 'type'
                rtn.is_type_annotation = True
                construct = mdl_lint.symbol_table.get('atomic', rtn.value, None)
            else:
                mdl_lint.symbol_table._error_not_defined(rtn, rtn.value, 'type or callable')

            if rtn.value in self.imported_rtns:
                pos = common.position.ProgramAreaNear(rtn)
                raise GbsLintException(i18n.i18n('%s %%s was already imported' % (construct_type,)) % (rtn.value,), pos)
            self.imported_rtns[rtn.value] = True

            self.symbol_table.add(construct, area=common.position.ProgramAreaNear(rtn))
Example #45
0
 def _result(self, tit, out, board, head_pos, keyvals):
     if board is not None:
         out.write('  <h3>%s</h3>\n' % (tit, ))
         out.write(html_board(board, draw_head=self._options['check_head']))
     if self._options['check_result']:
         out.write('  <h3>%s</h3>\n' % (i18n.i18n('Returned variables'), ))
         if len(keyvals) == 0:
             out.write('  <tt>&lt;%s&gt;</tt>\n' %
                       (i18n.i18n('No returned variables'), ))
         else:
             out.write('  <div class="returned_vars">\n')
             for k, v in keyvals:
                 out.write('<p><tt>%s -&gt; %s</tt></p>\n' % (k, v))
             out.write('  </div>\n')
Example #46
0
def run_runnable(runnable, **options):
    try:
        board = lang.gbs_board.Board((1, 1))
        if options['from']:
            inb = options['from']
            if not os.path.exists(inb):
                report_error(i18n.i18n('Error'),
                             i18n.i18n('File %s does not exist') % (inb, ))
                return False
            fmt = options['from'].split('.')[-1]
            fmt = fmt.lower()
            if fmt not in lang.board.formats.AvailableFormats:
                fmt = lang.board.formats.DefaultFormat
            f = open(inb, 'r')
            board.load(f, fmt=fmt)
            f.close()
        else:
            if options['size']:
                board.clone_from(lang.gbs_board.Board(options['size']))
                board.randomize_contents()
            else:
                board.randomize_full()

        initial_board = board.clone()
        result = runnable.run(board)

        if options['to']:
            f = open(options['to'], 'w')
            fmt = options['to'].split('.')[-1]
            fmt = fmt.lower()
            if fmt not in lang.board.formats.AvailableFormats:
                fmt = lang.board.formats.DefaultFormat
            board.dump(f, fmt=fmt, style=style(options))
            f.close()

        if options['print-input']:
            print(initial_board)
        if options['print-board']:
            print(board)
        if options['print-retvals']:
            for var, val in result:
                print('%s -> %s' % (var, val))
            if not options['print-board']:
                print('OK')

    except common.utils.SourceException as exception:
        report_program_error(exception.error_type(), exception.msg,
                             exception.area)

    return True
Example #47
0
  def _input_board(self, out):
    out.write('  <div id="test_case" class="info_frame" style="background:#c0c0c0">\n')

    out.write('  <h3>%s</h3>\n' % (i18n.i18n('Initial board'),))
    input_board = self._initial_board
    out.write(html_board(input_board))

    if self._source_code:
      out.write('  <h3>%s</h3>\n' % (i18n.i18n('Source code'),))
      out.write('<pre>')
      out.write(html_escape(pprint(self._source_code, self._test_case.run_name())))
      out.write('</pre>')

    out.write('  </div>\n')
Example #48
0
 def compile(self, filename, program_text):
     # Parse gobstones script
     self.api.log(i18n.i18n('Parsing.'))
     tree = self.parse(program_text, filename)            
     assert tree
     # Explode macros
     self.api.log(i18n.i18n('Exploding program macros.'))            
     self.explode_macros(tree)
     # Check semantics, liveness and types
     self.check(tree)
     # Compile program
     self.api.log(i18n.i18n('Compiling.'))
     compiled_program = self.compile_program(tree)
     return GobstonesRun().initialize(tree, compiled_program)
Example #49
0
 def compile(self, filename, program_text):
     # Parse gobstones script
     self.api.log(i18n.i18n('Parsing.'))
     tree = self.parse(program_text, filename)
     assert tree
     # Explode macros
     self.api.log(i18n.i18n('Exploding program macros.'))
     self.explode_macros(tree)
     # Check semantics, liveness and types
     self.check(tree)
     # Compile program
     self.api.log(i18n.i18n('Compiling.'))
     compiled_program = self.compile_program(tree)
     return GobstonesRun().initialize(tree, compiled_program)
 def build_special_key_constants(self):
     return [
             self.build_key_constant(i18n.i18n("K_ARROW_LEFT"), GobstonesKeys.ARROW_LEFT),
             self.build_key_constant(i18n.i18n("K_ARROW_UP"), GobstonesKeys.ARROW_UP),
             self.build_key_constant(i18n.i18n("K_ARROW_RIGHT"), GobstonesKeys.ARROW_RIGHT),
             self.build_key_constant(i18n.i18n("K_ARROW_DOWN"), GobstonesKeys.ARROW_DOWN),
             self.build_key_constant('K_CTRL_D', 4),
             self.build_key_constant('K_ENTER', 13),
             self.build_key_constant('K_SPACE', 32),
             self.build_key_constant('K_DELETE', 46),
             self.build_key_constant('K_BACKSPACE', 8),
             self.build_key_constant('K_TAB', 9),
             self.build_key_constant('K_ESCAPE', 27),
             ]
Example #51
0
 def check_unused_assignVarTuple1(self, tree):
   varnames = [v.value for v in tree.children[1].children]
   any_used = False
   for v in varnames:
     if v in tree.live_out:
       any_used = True
       break
   if not any_used:
     if len(varnames) == 1:
       msg = i18n.i18n('Variable "%s" defined but not used') % (varnames[0],)
     else:
       msg = i18n.i18n('Variables "(%s)" defined but not used') % (
                 ', '.join(varnames),)
     area = common.position.ProgramAreaNear(tree)
     raise GbsUnusedVarException(msg, area)
Example #52
0
 def _add_index(self, varName, tree):
     var = self.symbol_table.check_not_defined_or_defined_as(
         tree, varName, 'atomic', ['index', 'variable', 'parameter'])
     if var is None:
         self.symbol_table.add(lang.gbs_constructs.UserIndex(varName, tree))
     elif var.type() == 'variable':
         msg = i18n.i18n(
             'Index of a foreach cannot be a variable: "%s"') % (varName, )
         area = common.position.ProgramAreaNear(tree)
         raise GbsLintException(msg, area)
     elif var.type() == 'parameter':
         msg = i18n.i18n(
             'Index of a foreach cannot be a parameter: "%s"') % (varName, )
         area = common.position.ProgramAreaNear(tree)
         raise GbsLintException(msg, area)
Example #53
0
 def parse_error(self, top, _previous_token, token):
     "Raises a ParserException describing a parse error."
     if is_nonterminal(top):
         follow = self._followups(top)
     else:
         follow = [Token.type_description(top)]
     if len(follow) == 1:
         msg = i18n.i18n('Found: %s\nExpected: %s') % (token, follow[0])
     else:
         msg = ''
         msg += i18n.i18n('\n'.join([
             'Found: %s', 'Expected one of the following tokens:'
         ])) % (token, )
         msg += '\n' + common.utils.indent('\n'.join(follow))
     raise ParserException(msg, common.position.ProgramAreaNear(token))
Example #54
0
 def _set_routine_definition_type(self, tree, prfn, name, params, body):
     """Given a context with types for the parameters and local
     variables in a routine, build the type for this routine
     and unify it with its type in the global context.
     For instance if the function "f" has a parameter "x",
     and returns an expression, take the type "s" for "x"
     from the local context, the type "t" for the returned
     expression. Build the type "s -> t" for the function
     and unify that with any type information previously
     known for "f". This requires that the body of the routine
     has already been typechecked."""
     param_types = []
     for p in params.children:
         param_types.append(self.context[p.value])
     param_types = lang.gbs_type.GbsTupleType(param_types)
     if prfn == 'procedure':
         def_type = lang.gbs_type.GbsProcedureType(param_types)
     elif prfn == 'function':
         return_types = self._return_type(prfn, name, params, body)
         def_type = lang.gbs_type.GbsFunctionType(param_types, return_types)
     elif prfn == 'entrypoint' and (name.value == 'program'
                                    or name.value == 'interactive'):
         def_type = lang.gbs_type.GbsEntryPointType()
     else:
         assert False
     expected = self.global_context[name.value].instantiate()
     try:
         lang.gbs_type.unify(expected, def_type)
         if prfn == 'function':  #[TODO] Check
             freevars = def_type.freevars()
             if len(freevars) > 0:
                 def_type = lang.gbs_type.GbsForallType(freevars, def_type)
                 self.global_context[name.value] = def_type
         tree.type_annot = def_type
     except lang.gbs_type.UnificationFailedException as e:
         area = common.position.ProgramAreaNear(tree)
         if prfn == 'procedure':
             msg = i18n.i18n('procedure "%s" should take: %s\n' +
                             'But takes: %s') % (name.value,
                                                 expected.paramtype(),
                                                 def_type.paramtype())
         else:
             msg = i18n.i18n(
                 'function "%s" should take: %s and return: %s\n' +
                 'But takes: %s and returns: %s') % (
                     name.value, expected.paramtype(), expected.restype(),
                     def_type.paramtype(), def_type.restype())
         self.error(GbsTypeInferenceException(msg, area))
Example #55
0
 def check_unused_assignVarName(self, tree, var=None):
   if var is None:
     var = tree.children[1].children[1]
   if var.value not in tree.live_out:
     msg = i18n.i18n('Variable "%s" defined but not used') % (var.value,)
     area = common.position.ProgramAreaNear(tree)
     raise GbsUnusedVarException(msg, area)
Example #56
0
 def gen_expression(self, tree):
   "Returns the GEN set of an expression."
   if tree.live_gen is not None:
     return tree.live_gen
   exptype = tree.children[0]
   dispatch = {
     'or': self.gen_binary_op,
     'and': self.gen_binary_op,
     'not': self.gen_unary_op,
     'relop': self.gen_binary_op,
     'addsub': self.gen_binary_op,
     'mul': self.gen_binary_op,
     'divmod': self.gen_binary_op,
     'pow': self.gen_binary_op,
     'listop': self.gen_binary_op,
     'projection': self.gen_binary_op_left_only,
     'constructor': self.gen_binary_op,
     'match': self.gen_match,
     'varName': self.gen_varName,
     'funcCall': self.gen_funcCall,
     'unaryMinus': self.gen_unary_op,
     'literal': self.gen_literal,
     'type': self.gen_type,
   }
   if exptype in dispatch:
       tree.live_gen = dispatch[exptype](tree)
   else:
       msg = i18n.i18n('Unknown expression: %s') % (exptype,)
       area = common.position.ProgramAreaNear(tree)
       raise GbsLivenessException(msg, area)
   return tree.live_gen