예제 #1
0
파일: entities.py 프로젝트: gvk489/liam2
 def parse_expr(self, k, v, context):
     if isinstance(v, (bool, int, float)):
         return Assignment(k, self, v)
     elif isinstance(v, basestring):
         return Assignment(k, self, parse(v, context))
     else:
         # lets be explicit about it
         return None
예제 #2
0
 def parse_expr(self, k, v, context):
     if isinstance(v, (bool, int, float)):
         return Assignment(k, self, v)
     elif isinstance(v, basestring):
         return Assignment(k, self, parse(v, context))
     else:
         # lets be explicit about it
         return None
예제 #3
0
    def all_symbols(self, global_context):
        from links import PrefixingLink

        symbols = WarnOverrideDict(self.variables.copy())
        local_context = global_context.copy()
        local_context[self.name] = symbols
        local_context['__entity__'] = self.name
        macros = dict((k, parse(v, local_context))
                      for k, v in self.macro_strings.iteritems())
        symbols.update(macros)
        symbols['other'] = PrefixingLink(self, macros, self.links, '__other_')
        symbols.update(self.methods)
        return symbols
예제 #4
0
파일: entities.py 프로젝트: gvk489/liam2
    def all_symbols(self, global_context):
        from links import PrefixingLink

        symbols = WarnOverrideDict(self.variables.copy())
        local_context = global_context.copy()
        local_context[self.name] = symbols
        local_context['__entity__'] = self.name
        macros = dict((k, parse(v, local_context))
                      for k, v in self.macro_strings.iteritems())
        symbols.update(macros)
        symbols['other'] = PrefixingLink(self, macros, self.links, '__other_')
        symbols.update(self.methods)
        return symbols
예제 #5
0
파일: console.py 프로젝트: gvk489/liam2
    def execute(self, s):
        entity = self.entity
        if entity is None:
            raise Exception(entity_required)

        period = self.period
        if period is None:
            raise Exception(period_required)

        entity_name = self.entity.name
        parse_ctx = self.parse_ctx.copy()
        local_parse_ctx = parse_ctx[entity_name].copy()

        # add all currently defined temp_variables because otherwise
        # local variables (defined within a function) wouldn't be available
        local_parse_ctx.update((name, Variable(entity, name))
                               for name in entity.temp_variables.keys())
        parse_ctx[entity_name] = local_parse_ctx
        expr = parse(s, parse_ctx, interactive=True)
        result = expr_eval(expr, self.eval_ctx)
        if result is None:
            print("done.")
        return result
예제 #6
0
def evaluate(s, parse_ctx, eval_ctx):
    expr = parse(s, parse_ctx)
    return expr.evaluate(eval_ctx)
예제 #7
0
 def parse_expressions(self, items, context):
     """
     items -- a list of tuples (name, process_string)
     context -- parsing context
                a dict of all symbols available for all entities
     """
     processes = []
     for k, v in items:
         if k == 'while':
             if not isinstance(v, dict):
                 raise ValueError("while is a reserved keyword")
             cond = parse(v['cond'], context)
             assert isinstance(cond, Expr)
             code = self.parse_process_group("while:code", v['code'],
                                             context, purge=False)
             process = While(k, self, cond, code)
         else:
             process = self.parse_expr(k, v, context)
             if process is None:
                 if self.ismethod(v):
                     if isinstance(v, list):
                         # v should be a list of dicts (assignments) or
                         # strings (actions)
                         argnames, code_def, result_def = [], v, None
                     else:
                         assert isinstance(v, dict)
                         args_def = v.get('args', '')
                         argnames = [a.strip()
                                     for a in args_def.split(',')
                                     if a != '']
                         code_def = v.get('code', [])
                         result_def = v.get('return')
                     method_context = self.get_group_context(context,
                                                             argnames)
                     code = self.parse_process_group("func:code", code_def,
                                                     method_context,
                                                     purge=False)
                     #TODO: use code.predictors instead (but it currently
                     # fails for some reason) or at least factor this out
                     # with the code in parse_process_group
                     group_expressions = [elem.items()[0]
                                          if isinstance(elem, dict)
                                          else (None, elem)
                                          for elem in code_def]
                     group_predictors = \
                         self.collect_predictors(group_expressions)
                     method_context = self.get_group_context(
                         method_context, group_predictors)
                     result = parse(result_def, method_context)
                     assert result is None or isinstance(result, Expr)
                     process = Function(k, self, argnames, code, result)
                 elif isinstance(v, dict) and 'predictor' in v:
                     raise ValueError("Using the 'predictor' keyword is "
                                      "not supported anymore. "
                                      "If you need several processes to "
                                      "write to the same variable, you "
                                      "should rather use procedures.")
                 else:
                     raise Exception("unknown expression type for %s: %s"
                                     % (k, type(v)))
         processes.append((k, process))
     return processes
예제 #8
0
파일: entities.py 프로젝트: gvk489/liam2
    def parse_expressions(self, items, context, functions_only=False):
        """
        items -- a list of tuples (name, process_string)
        context -- parsing context
                   a dict of all symbols available for all entities
        functions_only -- whether non-functions processes are allowed
        """
        processes = []
        for k, v in items:
            if k == 'while':
                if isinstance(v, dict):
                    raise SyntaxError("""
This syntax for while is not supported anymore:
  - while:
      cond: {cond_expr}
      code:
          - ...
Please use this instead:
  - while {cond_expr}:
      - ...
""".format(cond_expr=v['cond']))
                else:
                    raise ValueError("while is a reserved keyword")
            elif k is not None and k.startswith('while '):
                if not isinstance(v, list):
                    raise SyntaxError("while is a reserved keyword")
                cond = parse(k[6:].strip(), context)
                assert isinstance(cond, Expr)
                code = self.parse_process_group("while_code",
                                                v,
                                                context,
                                                purge=False)
                process = While(k, self, cond, code)
            elif k == 'return':
                e = SyntaxError("return is a reserved keyword. To return "
                                "from a function, use 'return expr' "
                                "instead of 'return: expr'")
                e.liam2context = "while parsing: return: {}".format(v)
                raise e
            elif k is None and isinstance(v, str) and v.startswith('return'):
                assert len(v) == 6 or v[6] == ' '
                if len(v) > 6:
                    result_def = v[7:].strip()
                else:
                    result_def = None
                result_expr = parse(result_def, context)
                process = Return(None, self, result_expr)
            else:
                process = self.parse_expr(k, v, context)
                if process is not None and functions_only:
                    if k in self.fields.names:
                        msg = """defining a process outside of a function is
deprecated because it is ambiguous. You should:
 * wrap the '{name}: {expr}' assignment inside a function like this:
        compute_{name}:  # you can name it any way you like but simply \
'{name}' is not recommended !
            - {name}: {expr}
 * update the simulation.processes list to use 'compute_{name}' (the function \
name) instead of '{name}'.
"""
                    else:
                        msg = """defining a process outside of a function is \
deprecated because it is ambiguous.
1) If '{name}: {expr}' is an assignment ('{name}' stores the result of \
'{expr}'), you should:
 * wrap the assignment inside a function, for example, like this:
        compute_{name}:  # you can name it any way you like but simply \
'{name}' is not recommended !
            - {name}: {expr}
 * update the simulation.processes list to use 'compute_{name}' (the function \
name) instead of '{name}'.
 * add '{name}' in the entities fields with 'output: False'
2) otherwise if '{expr}' is an expression which does not return any value, you \
can simply transform it into a function, like this:
        {name}:
            - {expr}
"""
                    warnings.warn(msg.format(name=k, expr=v),
                                  UserDeprecationWarning)
                if process is None:
                    if self.ismethod(v):
                        if isinstance(v, dict):
                            args = v.get('args', '')
                            code = v.get('code', '')
                            result = v.get('return', '')
                            oldargs = "\n      args: {}".format(args) \
                                if args else ''
                            oldcode = "\n      code:\n          - ..." \
                                if code else ''
                            newcode = "\n      - ..." if code else ''
                            oldresult = "\n      return: " + result \
                                if result else ''
                            newresult = "\n      - return " + result \
                                if result else ''
                            template = """
This syntax for defining functions with arguments or a return value is not
supported anymore:
  {funcname}:{oldargs}{oldcode}{oldresult}

Please use this instead:
  {funcname}({newargs}):{newcode}{newresult}"""
                            msg = template.format(funcname=k,
                                                  oldargs=oldargs,
                                                  oldcode=oldcode,
                                                  oldresult=oldresult,
                                                  newargs=args,
                                                  newcode=newcode,
                                                  newresult=newresult)
                            raise SyntaxError(msg)

                        assert isinstance(v, list)
                        # v should be a list of dicts (assignments) or
                        # strings (actions)
                        if "(" in k:
                            k, args = split_signature(k)
                            argnames = argspec(args).args
                            code_def, result_def = v, None
                        else:
                            argnames, code_def, result_def = [], v, None
                        method_context = self.get_group_context(
                            context, argnames)
                        code = self.parse_process_group(k + "_code",
                                                        code_def,
                                                        method_context,
                                                        purge=False)
                        # TODO: use code.predictors instead (but it currently
                        # fails for some reason) or at least factor this out
                        # with the code in parse_process_group
                        group_expressions = [
                            elem.items()[0] if isinstance(elem, dict) else
                            (None, elem) for elem in code_def
                        ]
                        group_predictors = \
                            self.collect_predictors(group_expressions)
                        method_context = self.get_group_context(
                            method_context, group_predictors)
                        result_expr = parse(result_def, method_context)
                        assert result_expr is None or \
                            isinstance(result_expr, Expr)
                        process = Function(k, self, argnames, code,
                                           result_expr)
                    elif isinstance(v, dict) and 'predictor' in v:
                        raise ValueError("Using the 'predictor' keyword is "
                                         "not supported anymore. "
                                         "If you need several processes to "
                                         "write to the same variable, you "
                                         "should rather use functions.")
                    elif k is None and v is None:
                        raise ValueError("empty process found ('-')")
                    else:
                        raise Exception("unknown expression type for "
                                        "%s: %s (%s)" % (k, v, type(v)))
            processes.append((k, process))
        return processes
예제 #9
0
    def parse_expressions(self, items, context, functions_only=False):
        """
        items -- a list of tuples (name, process_string)
        context -- parsing context
                   a dict of all symbols available for all entities
        functions_only -- whether non-functions processes are allowed
        """
        processes = []
        for k, v in items:
            if k == 'while':
                if isinstance(v, dict):
                    raise SyntaxError("""
This syntax for while is not supported anymore:
  - while:
      cond: {cond_expr}
      code:
          - ...
Please use this instead:
  - while {cond_expr}:
      - ...
""".format(cond_expr=v['cond']))
                else:
                    raise ValueError("while is a reserved keyword")
            elif k is not None and k.startswith('while '):
                if not isinstance(v, list):
                    raise SyntaxError("while is a reserved keyword")
                cond = parse(k[6:].strip(), context)
                assert isinstance(cond, Expr)
                code = self.parse_process_group("while_code", v, context,
                                                purge=False)
                process = While(k, self, cond, code)
            elif k == 'return':
                e = SyntaxError("return is a reserved keyword. To return "
                                "from a function, use 'return expr' "
                                "instead of 'return: expr'")
                e.liam2context = "while parsing: return: {}".format(v)
                raise e
            elif k is None and isinstance(v, str) and v.startswith('return'):
                assert len(v) == 6 or v[6] == ' '
                if len(v) > 6:
                    result_def = v[7:].strip()
                else:
                    result_def = None
                result_expr = parse(result_def, context)
                process = Return(None, self, result_expr)
            else:
                process = self.parse_expr(k, v, context)
                if process is not None and functions_only:
                    if k in self.fields.names:
                        msg = """defining a process outside of a function is
deprecated because it is ambiguous. You should:
 * wrap the '{name}: {expr}' assignment inside a function like this:
        compute_{name}:  # you can name it any way you like but simply \
'{name}' is not recommended !
            - {name}: {expr}
 * update the simulation.processes list to use 'compute_{name}' (the function \
name) instead of '{name}'.
"""
                    else:
                        msg = """defining a process outside of a function is \
deprecated because it is ambiguous.
1) If '{name}: {expr}' is an assignment ('{name}' stores the result of \
'{expr}'), you should:
 * wrap the assignment inside a function, for example, like this:
        compute_{name}:  # you can name it any way you like but simply \
'{name}' is not recommended !
            - {name}: {expr}
 * update the simulation.processes list to use 'compute_{name}' (the function \
name) instead of '{name}'.
 * add '{name}' in the entities fields with 'output: False'
2) otherwise if '{expr}' is an expression which does not return any value, you \
can simply transform it into a function, like this:
        {name}:
            - {expr}
"""
                    warnings.warn(msg.format(name=k, expr=v),
                                  UserDeprecationWarning)
                if process is None:
                    if self.ismethod(v):
                        if isinstance(v, dict):
                            args = v.get('args', '')
                            code = v.get('code', '')
                            result = v.get('return', '')
                            oldargs = "\n      args: {}".format(args) \
                                if args else ''
                            oldcode = "\n      code:\n          - ..." \
                                if code else ''
                            newcode = "\n      - ..." if code else ''
                            oldresult = "\n      return: " + result \
                                if result else ''
                            newresult = "\n      - return " + result \
                                if result else ''
                            template = """
This syntax for defining functions with arguments or a return value is not
supported anymore:
  {funcname}:{oldargs}{oldcode}{oldresult}

Please use this instead:
  {funcname}({newargs}):{newcode}{newresult}"""
                            msg = template.format(funcname=k, oldargs=oldargs,
                                                  oldcode=oldcode,
                                                  oldresult=oldresult,
                                                  newargs=args, newcode=newcode,
                                                  newresult=newresult)
                            raise SyntaxError(msg)

                        assert isinstance(v, list)
                        # v should be a list of dicts (assignments) or
                        # strings (actions)
                        if "(" in k:
                            k, args = split_signature(k)
                            argnames = argspec(args).args
                            code_def, result_def = v, None
                        else:
                            argnames, code_def, result_def = [], v, None
                        method_context = self.get_group_context(context,
                                                                argnames)
                        code = self.parse_process_group(k + "_code", code_def,
                                                        method_context,
                                                        purge=False)
                        # TODO: use code.predictors instead (but it currently
                        # fails for some reason) or at least factor this out
                        # with the code in parse_process_group
                        group_expressions = [elem.items()[0]
                                             if isinstance(elem, dict)
                                             else (None, elem)
                                             for elem in code_def]
                        group_predictors = \
                            self.collect_predictors(group_expressions)
                        method_context = self.get_group_context(
                            method_context, group_predictors)
                        result_expr = parse(result_def, method_context)
                        assert result_expr is None or \
                            isinstance(result_expr, Expr)
                        process = Function(k, self, argnames, code, result_expr)
                    elif isinstance(v, dict) and 'predictor' in v:
                        raise ValueError("Using the 'predictor' keyword is "
                                         "not supported anymore. "
                                         "If you need several processes to "
                                         "write to the same variable, you "
                                         "should rather use functions.")
                    elif k is None and v is None:
                        raise ValueError("empty process found ('-')")
                    else:
                        raise Exception("unknown expression type for "
                                        "%s: %s (%s)" % (k, v, type(v)))
            processes.append((k, process))
        return processes