コード例 #1
0
def test_StatementVisitor__visit_NodeCompileStmt__code_generation_1(): #IGNORE:C01111
    #py.test.skip('Test StatementVisitor.visit_NodeCompileStmt')
    print 'Test StatementVisitor.visit_NodeCompileStmt:'
    from freeode.interpreter import (Interpreter, IFloat, SimlFunction)
    from freeode.ast import (DotName)

    prog_text = \
'''
class A:
    data b: Float
     
    func dynamic(this):
        b = 2

compile A
'''

    #create the interpreter
    intp = Interpreter()
    #run program
    intp.interpret_module_string(prog_text, None, 'test')
  
    #print intp.modules['test']
    #print intp.get_compiled_objects()[0] 

    #there must be one compiled object present
    assert len(intp.get_compiled_objects()) == 1
    
    comp_obj = intp.get_compiled_objects()[0]
    #the attributes b and dynamic must exist
    assert isinstance(comp_obj.get_attribute(DotName('b')), IFloat)
    assert isinstance(comp_obj.get_attribute(DotName('dynamic')), SimlFunction)
    assert len(comp_obj.get_attribute(DotName('dynamic')).statements) == 1
コード例 #2
0
ファイル: test_pygenerator.py プロジェクト: eike-welk/freeode
def test_ProgramGenerator__create_program_2():
    msg = \
    ''' 
    Test ProgramGenerator.create_program: 
    Test program with additional initialization function.
    Load program as module and test init_*** function.
    '''
    #skip_test(msg)
    print msg
    
    import os
    from freeode.pygenerator import ProgramGenerator
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
class A:
    data x: Float 
    data b: Float param
    
    #This is the additional initialization function.
    func init_b(this, in_b):
        b = in_b #set parameter
        x = 0    #set initial value
                                                       #10     
    func initialize(this):
        b = 0.1 #set parameter
        x = 0   #set initial value
        
    func dynamic(this):
        $x = b
        
compile A
'''
    
    #interpret the compile time code
    intp = Interpreter()
    intp.interpret_module_string(prog_text, 'foo.siml', '__main__')
    #create the output text
    pg = ProgramGenerator()
    pg.create_program('foo.siml', intp.get_compiled_objects())
    #print pg.get_buffer()
    
    #write the buffer into a file, import the file as a module
    progname = 'testprog_ProgramGenerator__create_program_2'
    prog_text_file = open(progname + '.py','w')
    prog_text_file.write(pg.get_buffer())
    prog_text_file.close()
    module = __import__(progname)
    
    #test the generated module
    A = module.A
    a = A()
    #call generated init_b(...) function
    a.init_b(42)
    assert a.param.b == 42
    
    #clean up
    os.remove(progname + '.py')
    os.remove(progname + '.pyc')
コード例 #3
0
def test_graph_function_1(): #IGNORE:C01111
    #py.test.skip('Test the print function. - code generation for: user defined class.')
    print 'Test the print function. - code generation for: user defined class.'
    from freeode.interpreter import Interpreter
    from freeode.ast import DotName
    
    prog_text = \
'''
class A:
    data c: Float
    
    func final(this):
        graph(c)
        
compile A
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
  
#    print
#    print 'module after interpreter run: ---------------------------------'
#    print intp.modules['test']

    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #print sim
    
    #get the final function with the generated code
    final = sim.get_attribute(DotName('final'))
    assert len(final.statements) == 1
コード例 #4
0
def test_ProgramGenerator__create_program():
    msg = ''' Test ProgramGenerator.create_program: 
    Just see if function does not crash.
    '''
    #py.test.skip(msg)
    print msg
    
    from freeode.pygenerator import ProgramGenerator
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
class A:
    data a: Float
    data b: Float param
    
    func initialize(this):
        b = 1
    
    func dynamic(this):
        $a = b
    
compile A
'''
    
    #interpret the compile time code
    intp = Interpreter()
    intp.interpret_module_string(prog_text, 'foo.siml', '__main__')
    #create the output text
    pg = ProgramGenerator()
    pg.create_program('foo.siml', intp.get_compiled_objects())
    print pg.get_buffer()
コード例 #5
0
ファイル: test_pygenerator.py プロジェクト: eike-welk/freeode
def test_ProgramGenerator__create_program_1():
    msg = \
    ''' 
    Test ProgramGenerator.create_program: 
    Test basic functions of the compiler. Loads generated program as module.
    '''
    #skip_test(msg)
    print msg
    
    import os
    from freeode.pygenerator import ProgramGenerator
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
class A:
    data x: Float
    data b: Float param
    
    func initialize(this):
        x = 0
        b = 1
        solution_parameters(duration = 30, reporting_interval = 0.1)
    
    func dynamic(this):
        $x = b
    
compile A
'''
    
    #interpret the compile time code
    intp = Interpreter()
    intp.interpret_module_string(prog_text, 'foo.siml', '__main__')
    #create the output text
    pg = ProgramGenerator()
    pg.create_program('foo.siml', intp.get_compiled_objects())
    #print pg.get_buffer()
    
    #write the buffer into a file, import the file as a module
    progname = 'testprog_ProgramGenerator__create_program_1'
    prog_text_file = open(progname + '.py','w')
    prog_text_file.write(pg.get_buffer())
    prog_text_file.close()
    module = __import__(progname)
    
    #test the generated module
    A = module.A
    a = A()
    #call generated initialize(...) function
    a.initialize()
    assert a.param.b == 1
    #solve (trivial) ODE and test solution
    a.simulateDynamic()
    x_vals = a.getResults()['x']
    assert abs(x_vals[-1] - 30) < 1e-6
    
    #clean up
    os.remove(progname + '.py')
    os.remove(progname + '.pyc')
コード例 #6
0
def test_unknown_const_1(): #IGNORE:C01111
    msg = '''Test correct treatment of unknown constants.'''
    py.test.skip(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations, DataFlowChecker
    from freeode.interpreter import (Interpreter, IFloat) 
    from freeode.ast import DotName, NodeAssignment

    prog_text = \
'''
data c1: Float const

class A:
    data a, b: Float
    data c2: Float const
    
    func dynamic(this):       
        a = c1
        b = c2

compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print sim
    #get attributes
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
#    c = sim.get_attribute(DotName('c1'))
#    c = sim.get_attribute(DotName('c2'))
    #get generated main function
    dyn = sim.get_attribute(DotName('dynamic'))
    hexid = lambda x: hex(id(x))
    print 'a:', hexid(a), ' b:', hexid(b)#,  ' c2:', hexid(c)
    
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)
    #check data flow of all functions
    fc = DataFlowChecker()
    fc.set_sim_object(sim)
    
    
    assert False, 'This program should raise an exceptions because unknown const attributes were used'
コード例 #7
0
def test_interpreter_dollar_operator_2(): #IGNORE:C01111
    msg = '''
    Test "$" operator. 
    Bug: $ operator did not work with attributes of user defined classes.
    Background: Class instantiation did not get parent refferences right.
    '''
    #py.test.skip(msg)
    print msg
    from freeode.interpreter import Interpreter, CallableObject, IFloat
    from freeode.ast import DotName, RoleStateVariable, RoleTimeDifferential

    prog_text = \
'''
class A:
    data z: Float
    
    func dynamic(this):
        $z = z

class B:
    data a: A

    func dynamic(this):
        a.dynamic()

compile B
'''

    #create the interpreter
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    #print intp.modules['test']
    #print intp.get_compiled_objects()[0]
    #TODO: Assertions

    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #get the attributes that we have defined
    az = sim.get_attribute(DotName('a.z'))
    az_dt = sim.get_attribute(DotName('a.z$time'))   #implicitly defined by $ operator
    dynamic = sim.get_attribute(DotName('dynamic'))
    #test some facts about the attributes
    assert isinstance(az, IFloat)        #a1 is state variable, because it 
    assert az.role == RoleStateVariable  #has derivative
    assert isinstance(az_dt, IFloat)     
    assert az_dt.role == RoleTimeDifferential # $a1 is time differential
    assert isinstance(dynamic, CallableObject)
    
    #test if assignment really is 'a1$time' = 'a1'
    assign = dynamic.statements[0]
    assert assign.target is az_dt
    assert assign.expression is az
コード例 #8
0
def test_function_return_value_roles_1(): #IGNORE:C01111
    '''
    User defined functions can be called from constant and from variable 
    environments. Test the roles of their return values.
    This test only involves fundamental types.
    '''
    #py.test.skip('Test roles of return values of user defined functions.')
    print 'Test roles of return values of user defined functions.'
    from freeode.interpreter import Interpreter
    from freeode.ast import (DotName, RoleConstant, RoleAlgebraicVariable)
    
    prog_text = \
'''
func plus2(x):
    data r: Float
    r = x + 2
    return r

data ac,bc: Float const
ac = 3
bc = plus2(ac)


class B:
    data av,bv: Float
    
    func dynamic(this):
        bv = plus2(av)
        
compile B
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
#    print
    mod = intp.modules['test']
#    print 'module after interpreter run: ---------------------------------'
#    print mod
    ac = mod.get_attribute(DotName('ac'))
    bc = mod.get_attribute(DotName('bc'))
    assert ac.role == RoleConstant
    assert bc.role == RoleConstant
    assert ac.value == 3
    assert bc.value == 5

#    #get flattened object
    sim = intp.get_compiled_objects()[0] 
#    print 'Flattened object: ---------------------------------'
#    print sim
    av = sim.get_attribute(DotName('av'))
    bv = sim.get_attribute(DotName('bv'))
    assert av.role == RoleAlgebraicVariable
    assert bv.role == RoleAlgebraicVariable
コード例 #9
0
def test_compile_statement_1(): #IGNORE:C01111
    msg = '''
    Test the compile statement 
    - Flattening and storage of functions' local variables'''
    #py.test.skip(msg)
    print msg
    from freeode.interpreter import Interpreter, IFloat, CallableObject
    from freeode.ast import DotName

    prog_text = \
'''
class A:
    data a1: Float 
    
    func foo(this, x):
        return x
        
    func dynamic(this):
        data b,c: Float
        b = foo(a1)
        c = foo(a1 + b)
        $a1 = b

compile A
'''

    #create the interpreter
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    #print intp.modules['test']
    #print intp.get_compiled_objects()[0] 
    
    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    
    #get the attributes that we have defined
    a1 = sim.get_attribute(DotName('a1'))
    a1_dt = sim.get_attribute(DotName('a1$time'))
    dynamic = sim.get_attribute(DotName('dynamic'))
    #test some facts about the attributes
    assert isinstance(a1, IFloat)
    assert isinstance(a1_dt, IFloat)
    assert isinstance(dynamic, CallableObject)

    #check number of attributes, most are automatically generated
    #attributes:           initialize, dynamic, final, 
    #instance variables:   a1, $a1, 
    #local variables:      A.dynamic.b, A.dynamic.c, 
    #intermediate result:  A.foo.x, (2nd call)
    assert len(sim.attributes) == 8
コード例 #10
0
def test_user_defined_class_roles_1(): #IGNORE:C01111
    '''
    The role keywords (const, param, variable, ...) should work with user 
    defined classes too.
    '''
    #py.test.skip('Test user defined classes with different roles.')
    print 'Test user defined classes with different roles.'
    from freeode.interpreter import Interpreter
    from freeode.ast import (DotName, RoleConstant, RoleAlgebraicVariable)
    
    prog_text = \
'''
class A:
    data a: Float

#use the class as a constant
data ac: A const
ac.a = 2

class B:
    #use the class as a variable
    data av: A 
    data v: Float
    
    func dynamic(this):
        av.a = v
        
compile B
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
  
#    print
    mod = intp.modules['test']
#    print 'module after interpreter run: ---------------------------------'
#    print mod
    ac = mod.get_attribute(DotName('ac'))
    a = ac.get_attribute(DotName('a'))
    assert a.role == RoleConstant

#    #get flattened object
    sim = intp.get_compiled_objects()[0] 
#    print 'Flattened object: ---------------------------------'
#    print sim
    av_a = sim.get_attribute(DotName('av.a'))
    assert av_a.role == RoleAlgebraicVariable
コード例 #11
0
def test_interpreter_expression_statement_1(): #IGNORE:C01111
    '''
    Unevaluated expressions also generate code.
    '''
    #py.test.skip('Test expression statement - code generation.')
    print 'Test expression statement - code generation.'
    from freeode.interpreter import Interpreter, IFloat, CallableObject
    from freeode.ast import DotName, NodeExpressionStmt

    prog_text = \
'''
class A:
    data a,b: Float
    
    func dynamic(this):
        1+2
        a+b

compile A
'''

    #create the interpreter and interpret the mini-program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    #print intp.modules['test']
    #print intp.get_compiled_objects()[0] 
    
    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #get the attributes that we have defined
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
    dynamic = sim.get_attribute(DotName('dynamic'))
    #test some facts about the attributes
    assert isinstance(a, IFloat)
    assert isinstance(b, IFloat)
    assert isinstance(dynamic, CallableObject)
    #only one statement is collected (a+b)
    assert len(dynamic.statements) == 1
    stmt0 = dynamic.statements[0]
    assert isinstance(stmt0, NodeExpressionStmt)
    assert stmt0.expression.operator == '+'
コード例 #12
0
def test_interpreter_dollar_operator_1(): #IGNORE:C01111
    msg = 'Test "$" operator. Basic capabililities.'
    #py.test.skip(msg)
    print msg
    from freeode.interpreter import Interpreter, IFloat, CallableObject
    from freeode.ast import DotName, RoleStateVariable, RoleTimeDifferential

    prog_text = \
'''
class A:
    data a1: Float 

    func dynamic(this):
        $a1 = a1

compile A
'''

    #create the interpreter
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    #print intp.modules['test']
    #print intp.get_compiled_objects()[0] 
    
    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #get the attributes that we have defined
    a1 = sim.get_attribute(DotName('a1'))
    a1_dt = sim.get_attribute(DotName('a1$time'))   #implicitly defined by $ operator
    dynamic = sim.get_attribute(DotName('dynamic'))
    
    #test some facts about the attributes
    assert isinstance(a1, IFloat)        #a1 is state variable, because it 
    assert a1.role == RoleStateVariable  #has derivative
    assert isinstance(a1_dt, IFloat)     
    assert a1_dt.role == RoleTimeDifferential # $a1 is a time differential
    assert isinstance(dynamic, CallableObject)
    
    #test if assignment really is 'a1$time' = 'a1'
    assign = dynamic.statements[0]
    assert assign.target is a1_dt
    assert assign.expression is a1
コード例 #13
0
def test_SimulationClassGenerator__create_sim_class_1():
    msg = ''' Test SimulationClassGenerator.create_sim_class: 
    Just see if function does not crash.
    '''
    #py.test.skip(msg)
    print msg
    
    import cStringIO
    from freeode.pygenerator import SimulationClassGenerator
    from freeode.interpreter import Interpreter
    #from freeode.simulatorbase import SimulatorBase
    
    prog_text = \
'''
class A:
    data a:Float
    data b: Float 
    data c: Float param
    
    func initialize(this):
        a = 1
        c = 2
        print(a)
    
    func dynamic(this):
        b = c
        $a = b * sin(a)
        
    func final(this):
        graph(a)
    
compile A
'''
    
    #interpret the compile time code
    intp = Interpreter()
    intp.interpret_module_string(prog_text, 'foo.siml', '__main__')
    flat_o = intp.get_compiled_objects()[0]
    #create the Python class definition as text
    buf = cStringIO.StringIO()
    cg = SimulationClassGenerator(buf)
    cg.create_sim_class('A', flat_o)
    cls_txt = buf.getvalue()
    print cls_txt
コード例 #14
0
def test_print_function_4(): #IGNORE:C01111
    #py.test.skip('Test the print function. - code generation for: user defined class.')
    print 'Test the print function. - code generation for: user defined class.'
    from freeode.interpreter import Interpreter
    from freeode.ast import DotName
    
    prog_text = \
'''
#print user defined class
class C:
    data a: Float 
    data b: String
    
    func __str__(this):
        return a.__str__() + ' and ' + b.__str__()
        #return ' and ' + b.__str__()


class A:
    data c: C
    
    func dynamic(this):
        print(c)
        
compile A
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
  
#    print
#    print 'module after interpreter run: ---------------------------------'
#    print intp.modules['test']

    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #print sim
    
    #get the dynamic function with the generated code
    dynamic = sim.get_attribute(DotName('dynamic'))
    assert len(dynamic.statements) == 1
コード例 #15
0
def test_print_function_3(): #IGNORE:C01111
    #py.test.skip('Test the print function. - code generation for: Float, String')
    print 'Test the print function. - code generation for: Float, String'
    from freeode.interpreter import Interpreter
    from freeode.ast import DotName
    
    prog_text = \
'''
class A:
    data a,b,foo: Float
    data bar: String
    
    func dynamic(this):
        #print known constants
        print(23)
        print('hello ',2, ' the world!')
        
        #print unknown value
        print(foo)
        print(bar)
        
        #print unevaluated expression
        print(a+b)
        
compile A
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
  
#    print
#    print 'module after interpreter run: ---------------------------------'
#    print intp.modules['test']

    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #print sim
    #get the dynamic function with the generated code
    dynamic = sim.get_attribute(DotName('dynamic'))
    assert len(dynamic.statements) == 5
コード例 #16
0
def test_MakeDataFlowDecorations_1(): #IGNORE:C01111
    msg = '''Test the creation of data flow annotations.'''
    #py.test.skip(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations
    from freeode.interpreter import (Interpreter, IFloat) 
    from freeode.ast import DotName, NodeAssignment

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c,d: Float
    
    func dynamic(this):       
        a = p1
        b = a - p2
        if a > p1:
            c = p1
            d = p1
        else:
            c = p2 
            d = p2

compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print sim
    #get attributes
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
    c = sim.get_attribute(DotName('c'))
    d = sim.get_attribute(DotName('d'))
    p1 = sim.get_attribute(DotName('p1'))
    p2 = sim.get_attribute(DotName('p2'))
    #get generated main function
    dyn = sim.get_attribute(DotName('dynamic'))    
    #print object ids in hex (for easier manual testing)
    hexid = lambda x: hex(id(x))
    print 'a:', hexid(a), ' b:', hexid(b),  ' c:', hexid(c),  ' d:', hexid(d), \
          ' p1:', hexid(p1),  ' p2:', hexid(p2) 

    #------- the test -------------------
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)
    #dd.decorate_main_function(dyn)

    #see if the inputs and outputs were detected correctly
    # a = p1   
    stmt = dyn.statements[0]
    assert stmt.inputs == set([p1])
    assert stmt.outputs == set([a])
    #  b = a - p2
    stmt = dyn.statements[1]
    assert stmt.inputs == set([a, p2])
    assert stmt.outputs == set([b])
    
    #'if' statement
    stmt = dyn.statements[2]
    #look at inputs
    assert stmt.inputs.issuperset(set([a, p1, p2])) 
    #there is an additional constant IFloat(1) in the condition of the else
    one_set = stmt.inputs - set([a, p1, p2])
    assert len(one_set) == 1
    one_obj = one_set.pop()
    assert one_obj == IFloat(1)
    #look at outputs
    assert stmt.outputs == set([c, d])
    
    #the dynamic function
    assert dyn.inputs == set([p1, p2, one_obj])
    assert dyn.outputs == set([a, b, c, d])
コード例 #17
0
ファイル: test_pygenerator.py プロジェクト: eike-welk/freeode
def test_ProgramGenerator__all_variables_visible():
    msg = \
    ''' 
    Tests if all variables are visible in all main functions.
    Especially tests for existence an correct treatment of the variable 'time'.
    Runs the generated program as an external program.
    
    References:
    Fixed bug #598632
        https://bugs.launchpad.net/freeode/+bug/598632
    Blueprint:
        https://blueprints.launchpad.net/freeode/+spec/final-main-function-specification
    '''
    #skip_test(msg)
    print msg
    
    import os
    from subprocess import Popen, PIPE
    from freeode.pygenerator import ProgramGenerator
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
class A:
    data x: Float
    data b: Float param
    
    func initialize(this):
        x = 0
        b = 1
        solution_parameters(duration = 30, reporting_interval = 0.1)
        print("initial-values: ", b, x, $x, time)
    
    func dynamic(this):
        $x = b
        if abs(x - time) > 1e-6:
            print('dynamic-error: x = ', x, ', time = ', time)
        else:
            pass
    
    func final(this):
        print("final-values: ", b, x, $x, time)
compile A
'''
    
    #interpret the compile time code
    intp = Interpreter()
    intp.interpret_module_string(prog_text, '--no-file-name--', '__main__')
    #create the output text
    pg = ProgramGenerator()
    pg.create_program('foo.siml', intp.get_compiled_objects())
    #print pg.get_buffer()
    
    #write the buffer into a file
    progname = 'prog_test_ProgramGenerator__all_variables_visible'
    prog_text_file = open(progname + '.py','w')
    prog_text_file.write(pg.get_buffer())
    prog_text_file.close()
    
    #run the generated program
    sim = Popen('python ' + progname + '.py', shell=True, stdout=PIPE)
    res_txt, _ = sim.communicate()
#    print 'Program output: \n', res_txt     
#    print  'Return code: ', sim.returncode
    #the program must say that it terminated successfully
    assert sim.returncode == 0

    #TODO: do the following with search_result_lines
    #Scan the program's output to check if it's working.
    init_vals, final_vals = [], []
    dyn_error = False
    for line in res_txt.split('\n'):
        if line.startswith('initial-values:'):
            vals = line.split()[1:]
            init_vals = map(float, vals)
        elif line.startswith('final-values:'):
            vals = line.split()[1:]
            final_vals = map(float, vals)
        elif line.startswith('dynamic-error:'):
            dyn_error = True
        
    #Test if the values that the program returns are correct
    b, x, d_x, time = init_vals
    assert b == 1 and x == 0 and d_x == 0 and time == 0
    b, x, d_x, time = final_vals
    assert b == 1 and x == 30 and d_x == 0 and time == 30
    assert dyn_error == False, 'Error in dynamic function detected'
    
    #clean up
    os.remove(progname + '.py')
コード例 #18
0
def test_interpreter_user_defined_operators_1(): #IGNORE:C01111
    '''
    User defined operators must be converted into multiple statements,
    that contain only operations on fundamental types. Intermediate results
    are kept in function local variables, that are stored by the compile 
    statement.
    
    The used Siml class simulates a geometric vector class.
    '''
    #py.test.skip('Test user defined operators - code generation.')
    print 'Test user defined operators - code generation.'
    from freeode.interpreter import Interpreter, IFloat, CallableObject
    from freeode.ast import DotName

    prog_text = \
'''
class Vec1D:
    data x: Float role_unknown

    func __add__(this, other):
        data res: Vec1D
        res.x = x + other.x
        return res
        
    func __assign__(this, other):
        x = other.x


class A:
    data a,b,c: Vec1D
    
    func dynamic(this):
        #--- invoke the operators ----
        c=a+b


compile A
'''

    #create the interpreter and interpret the mini-program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    #print intp.modules['test']
    #print intp.get_compiled_objects()[0] 
    
    #get flattened object
    sim = intp.get_compiled_objects()[0] 
    #get the attributes that we have defined
    a_x = sim.get_attribute(DotName('a.x'))
    b_x = sim.get_attribute(DotName('b.x'))
    c_x = sim.get_attribute(DotName('c.x'))
    dynamic = sim.get_attribute(DotName('dynamic'))
    #test some facts about the attributes
    assert isinstance(a_x, IFloat)
    assert isinstance(b_x, IFloat)
    assert isinstance(c_x, IFloat)
    assert isinstance(dynamic, CallableObject)
    
    assert len(dynamic.statements) == 2
    stmt0 = dynamic.statements[0]
    stmt1 = dynamic.statements[1]
    #first statement (res.x = 2*(x + other.x)) assigns to function local variable
    assert stmt0.target not in [a_x, b_x, c_x]
    assert stmt0.expression.operator == '+'
    #second statement (c=a+b) assigns to c.x
    assert stmt1.target is c_x
    #second statement assigns temporary result of previous computation to attribute c.x
    assert stmt0.target is stmt1.expression
コード例 #19
0
def test_VariableUsageChecker_1(): #IGNORE:C01111
    msg = '''Test checking of variable usage. Provoke all errors at least once.'''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations, VariableUsageChecker
    from freeode.interpreter import Interpreter
    from freeode.util import DotName, UserException#, aa_make_tree

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c: Float
    
    #illegal read of parameter p1
    func init_1(this):
        p2 = p1
        a = 0
        
    #illegal write to derivative $a
    func init_2(this):
        $a = 1
        p1 = 1
        p2 = 1
        a = 0
    
    #Missing assignment to parameter p1
    func init_3(this):
        p2 = 1
        a = 0
        
    #illegal write to state variable a
    func dynamic(this): 
        a = 2
        $a = p1
        b = a - p2
        c = p1
        
    #illegal write to state variable a
    func final(this):
        a = 2
        b = 1
        print(a, b, p1)
        
        
compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #aa_make_tree(sim)
    
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)

    #Find all input and output variables
    vu = VariableUsageChecker()
    vu.set_annotated_sim_object(sim) 
    
    #illegal read of parameter p1
    initialize = vu.main_funcs[DotName('init_1')]
    #vu.check_initialize_function(initialize) 
    assert_raises(UserException, 4500100, 
                  vu.check_initialize_function, initialize)
    
    #illegal write to derivative $a
    initialize = vu.main_funcs[DotName('init_2')]
    #vu.check_initialize_function(initialize) 
    assert_raises(UserException, 4500200, 
                  vu.check_initialize_function, initialize)
    
    #Missing assignment to parameter p1
    initialize = vu.main_funcs[DotName('init_3')]
    #vu.check_initialize_function(initialize) 
    assert_raises(UserException, 4500300, 
                  vu.check_initialize_function, initialize)
    
    #illegal write to state variable a
    dynamic = vu.main_funcs[DotName('dynamic')]
    #vu.check_dynamic_function(dynamic) 
    assert_raises(UserException, 4500200, 
                  vu.check_dynamic_function, dynamic)
    
    #illegal write to state variable a
    final = vu.main_funcs[DotName('final')]
    #vu.check_final_function(final) 
    assert_raises(UserException, 4500200, 
                  vu.check_final_function, final)
コード例 #20
0
ファイル: test_optimizer.py プロジェクト: eike-welk/freeode
def test_VariableUsageChecker_1(): #IGNORE:C01111
    msg = '''Test checking of variable usage. Simple program with no errors.
    Use individual checking functions.
    
    These are the rules:
    Constants (rules enforced in the interpreter):
        - All constants must be known.
        - No assignments to constants.
        
    Parameters:
        - All must be assigned in all init**** function.
        - No assignment to parameters elsewhere.
        
    Variables:
        - All derivatives must be assigned in dynamic function.
        - No states must be assigned in dynamic function.
        - All states must be assigned initial values in init*** function.
    '''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations, VariableUsageChecker
    from freeode.interpreter import Interpreter
    from freeode.util import DotName#, aa_make_tree

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c: Float
    
    func init_1(this, ext1, ext2):
        ext2 = 1 #not useful but legal for simplicity
        p1 = ext1
        p2 = 1
        a = 0
        
    func initialize(this):
        p1 = 1
        p2 = 1
        a = 0
        print(time)
        data lo: Float
        lo = p1
        
    func dynamic(this): 
        $a = p1
        b = a - p2
        
        if a > p1:
            c = p1
        else:
            c = p2 
        data lo: Float variable
        lo = p1


    func final(this):
        b = 1
        print(a, b, p1)
        data lo: Float variable
        lo = p1
        
        
compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print aa_make_tree(sim)
    #print aa_make_tree(sim.func_locals)
    
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)

    #Find all input and output variables
    vu = VariableUsageChecker()
    vu.set_annotated_sim_object(sim) 
    
    #Check the usage of the variables 
    init_1 = vu.main_funcs[DotName('init_1')]
    vu.check_initialize_function(init_1) 
    
    initialize = vu.main_funcs[DotName('initialize')]
    vu.check_initialize_function(initialize) 
    
    dynamic = vu.main_funcs[DotName('dynamic')]
    vu.check_dynamic_function(dynamic) 
    
    final = vu.main_funcs[DotName('final')]
    vu.check_final_function(final) 
コード例 #21
0
def test_pass_statement_1(): #IGNORE:C01111
    msg = '''
    Test the pass statement. Try the normal use case.
    - The pass statement does nothing it is necessary to create empty 
    functions and classes. 
    '''
    #py.test.skip(msg)
    print msg
    
    from freeode.interpreter import (Interpreter, siml_isinstance, 
                                     CallableObject, TypeObject, IFloat)
    from freeode.ast import DotName

    prog_text = \
'''
#empty class body
class Dummy:
    pass

data d: Dummy const


#empty function body
func f_dummy():
    pass
    
f_dummy()
    
    
#call class with pass statement in compiled code
class A:
    data x: Float 
    data d: Dummy
    
    func foo(this):
        pass
        
    func dynamic(this):
        foo()
        $x = 1

compile A
'''

    #create the interpreter
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    
    #test the module a bit
    mod = intp.modules['test']
    #print mod
    class_Dummy = mod.get_attribute(DotName('Dummy'))
    d = mod.get_attribute(DotName('d'))
    f_dummy = mod.get_attribute(DotName('f_dummy'))
    class_A = mod.get_attribute(DotName('A'))
    assert siml_isinstance(d, class_Dummy)
    assert isinstance(f_dummy, CallableObject)
    assert isinstance(class_A, TypeObject)

    #Test the compiled object
    flat_A = intp.get_compiled_objects()[0] 
    #print flat_A
    x = flat_A.get_attribute(DotName('x'))
    x_time = flat_A.get_attribute(DotName('x$time'))
    assert isinstance(x, IFloat)
    assert isinstance(x_time, IFloat)
    assert len(flat_A.attributes) == 5
コード例 #22
0
ファイル: test_optimizer.py プロジェクト: eike-welk/freeode
def test_check_simulation_objects_1(): #IGNORE:C01111
    msg = '''Test checking of variable usage. Simple program with no errors.
    Use high level checking function.
    '''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import check_simulation_objects
    from freeode.interpreter import Interpreter
#    from freeode.util import aa_make_tree

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c: Float
    
    func init_1(this, ext1, ext2):
        ext2 = 1 #not useful but legal for simplicity
        p1 = ext1
        p2 = 1
        a = 0
        
    func initialize(this):
        p1 = 1
        p2 = 1
        a = 0
        data lo: Float
        lo = p1
        
    func dynamic(this): 
        $a = p1
        b = a - p2
        
        if a > p1:
            c = p1
        else:
            c = p2 
        data lo: Float variable
        lo = p1


    func final(this):
        b = 1
        print(a, b, p1)
        data lo: Float variable
        lo = p1
        
        
compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #do the checks
    check_simulation_objects(intp.get_compiled_objects())
コード例 #23
0
def test_ProgramGenerator__create_program_3():
    msg = \
    ''' 
    Test ProgramGenerator.create_program: 
    Test most common language features.
    '''
    #py.test.skip(msg)
    print msg
    
    import os
    from freeode.pygenerator import ProgramGenerator
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
class A:
    data x: Float 
    data a, b, c, d, e: Float param

    func initialize(this):
        a = 2 * (3 + 4)               # = 14, test brackets
        b = a**0 / 0.1 % 9 - -a/a  # = 2, arithmetic operators
        
        #if statement should reduce to single assignment
        if -2**-3 == -(2 ** (-3)):    # tricky operator precedence
            c = 1                     # c = 1
        else:
            c = 0
        
        #if statement, comparison and logical operators
        if (a != 1 and not a == 1 or a == 1) and (a < 1 or a > 1):
            d = 1                     # d = 1
            e = sin(d * 3.1415)       # close to 0 #test function call
        else:
            d = 0
            e = sin(d * 3.1415)       # = 0  #test function call
            
        x = 0   #set initial value
        
    func dynamic(this):
        $x = b
        
compile A
'''
    
    #interpret the compile time code
    intp = Interpreter()
    intp.interpret_module_string(prog_text, 'foo.siml', '__main__')
    #create the output text
    pg = ProgramGenerator()
    pg.create_program('foo.siml', intp.get_compiled_objects())
    print pg.get_buffer()
    
    #write the buffer into a file, import the file as a module
    #progname must be unique! otherwise race condition!
    progname = 'testprog_ProgramGenerator__create_program_3'
    prog_text_file = open(progname + '.py','w')
    prog_text_file.write(pg.get_buffer())
    prog_text_file.close()
    module = __import__(progname)
    
    #test the generated module
    A = module.A
    a = A()
    #call generated init_b(...) function
    a.initialize()
    assert a.param.a == 14
    assert a.param.b == 2
    assert a.param.c == 1
    assert a.param.d == 1
    assert abs(a.param.e) < 0.001 #close to 0 
    
    #clean up
    os.remove(progname + '.py')
コード例 #24
0
ファイル: test_optimizer.py プロジェクト: eike-welk/freeode
def test_MakeDataFlowDecorations_1(): #IGNORE:C01111
    msg = '''Test the creation of data flow annotations.'''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations
    from freeode.interpreter import Interpreter, IFloat
    #from freeode.ast import NodeAssignment
    from freeode.util import DotName

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c,d: Float
                              #5 
    func dynamic(this):            
        a = p1
        b = a - p2
        if a > p1:
            c = p1           #10
            d = p1
        else:
            c = p2 
            d = p2
        print(a)

compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print sim
    #get attributes
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
    c = sim.get_attribute(DotName('c'))
    d = sim.get_attribute(DotName('d'))
    p1 = sim.get_attribute(DotName('p1'))
    p2 = sim.get_attribute(DotName('p2'))
    #get generated main function
    dyn = sim.get_attribute(DotName('dynamic'))    
    #print object ids in hex (for easier manual testing)
    hexid = lambda x: hex(id(x))
    print 'a:', hexid(a), ' b:', hexid(b),  ' c:', hexid(c),  ' d:', hexid(d), \
          ' p1:', hexid(p1),  ' p2:', hexid(p2) 

    #------- the test -------------------
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)
    #dd.decorate_main_function(dyn)

    #see if the inputs and outputs were detected correctly
    # a = p1--------------------------------------
    stmt0 = dyn.statements[0]
    assert stmt0.inputs == set([p1])
    assert stmt0.outputs == set([a])
    #  b = a - p2 --------------------------------
    stmt1 = dyn.statements[1]
    assert stmt1.inputs == set([a, p2])
    assert stmt1.outputs == set([b])
    
    #'if' statement ------------------------------
    stmt2 = dyn.statements[2]
    #look at inputs
    assert stmt2.inputs.issuperset(set([a, p1, p2])) 
    #there is an additional constant IFloat(1) in the condition of the else
    one_set = stmt2.inputs - set([a, p1, p2])
    assert len(one_set) == 1
    one_obj = one_set.pop()
    assert one_obj == IFloat(1)
    #look at outputs
    assert stmt2.outputs == set([c, d])
    
    #print(a) -------------------------------------
    stmt3 = dyn.statements[3]
    assert stmt3.inputs == set([a])
    assert stmt3.outputs == set()
    #the dynamic function as a whole --------------
    assert dyn.inputs == set([p1, p2, one_obj])
    assert dyn.outputs == set([a, b, c, d])
    
    #The input_locs, output_locs mappings for creating error messages
    #Parameter p1
    assert p1 not in dyn.output_locs #p1 is written nowhere
    p1_in_locs = dyn.input_locs[p1]
    assert len(p1_in_locs) == 4 #p1 read in 4 places
    assert p1_in_locs[0].line_no() == stmt0.loc.line_no() #read in statement 0
    assert p1_in_locs[1].line_no() == stmt2.loc.line_no() #read in 'if' statement
    #  + read in two lines in body of 'if' statement
#    for loc in p1_in_locs:
#        print loc
    #Variable a
    a_out_loc = dyn.output_locs[a]
    assert len(a_out_loc) == 1 #a written in 1 place
    assert a_out_loc[0].line_no() == stmt0.loc.line_no() #written in statement 0
    a_in_loc = dyn.input_locs[a]
    assert len(a_in_loc) == 3 #a read in 3 places
    assert a_in_loc[0].line_no() == stmt1.loc.line_no()
    assert a_in_loc[1].line_no() == stmt2.loc.line_no()
    assert a_in_loc[2].line_no() == stmt3.loc.line_no()