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()
def test_data_statement_simple_1(): #IGNORE:C01111
    #py.test.skip('Test data statement: create attributes')
    print 'Test data statement: create attributes'
    from freeode.interpreter import Interpreter, IFloat, IString
    from freeode.ast import DotName
    
    prog_text = \
'''
data a: Float const
data b: String const
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
  
    mod = intp.modules['test']
#    print
#    print 'module after interpreter run: ---------------------------------'
#    print mod
    
    a = mod.get_attribute(DotName('a'))
    assert isinstance(a, IFloat)
    b = mod.get_attribute(DotName('b'))
    assert isinstance(b, IString)
def test_argument_list_2(): #IGNORE:C01111
    msg = 'Test error in argument list - unknown argument.'
    #py.test.skip(msg)
    print msg
    from freeode.interpreter import Interpreter
    from freeode.ast import UserException
    
    prog_text = \
'''
func foo(a):
    return a

data a: Float    
foo(b=a)
'''
    #create the interpreter
    intp = Interpreter()
    
    try:
        #run mini program
        intp.interpret_module_string(prog_text, None, 'test')
    except UserException, e:
        print e
        assert e.errno == 3200260
        print 'Correct exception was raised.'
def test_print_function_1(): #IGNORE:C01111
    #py.test.skip('Test the print function. - actual printing, built in objects.')
    print 'Test the print function. - actual printing: Float, String, expression.'
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
#print known constants
print(23)
print('hello ',2, ' the world!')

#print unknown value
data foo: Float
data bar: String
print(foo)
print(bar)

#print unevaluated expression
data a,b: Float
print(a+b)
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
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
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
def test_interpreter_method_call(): #IGNORE:C01111
    #py.test.skip('Method calls do not work! Implement method wrappers!')
    print 'Test interpreter: method call ...............................................................'
    from freeode.interpreter import Interpreter, DotName

    prog_text = \
'''
print('start')

class A:
    data a1: Float const
    data a2: Float const
    
    func compute(this, x):
        print('in compute_a2 x=', x)
        return x + 2
        
data a: A const
a.a1 = a.compute(3)

#print('a.a1 = ', a.a1)

print('end')
'''

    #create the interpreter
    intp = Interpreter()
    #interpret the program
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    #print intp.modules['test']
  
    assert (intp.modules['test'].get_attribute(DotName('a'))
                                .get_attribute(DotName('a1')).value == 5)
def test_function_definition_and_call_1(): #IGNORE:C01111
    #py.test.skip('Test disabled')
    print 'Test interpreter object: function definition and function call ...............................................................'
    from freeode.interpreter import Interpreter, DotName

    prog_text = \
'''
print('start')

func foo(b):
    print('in foo. b = ', b)
    return b*b
    print('after return')

data a: Float const
a = 2*2 + foo(3*4) + foo(2)
print('a = ', a)

print('end')
'''
    #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']
    
    assert intp.modules['test'].get_attribute(DotName('a')).value == 2*2 + (3*4)**2 + 2**2
def test_data_statement_roles_1(): #IGNORE:C01111
    #py.test.skip('Test data statement: create attributes with different roles')
    print 'Test data statement: create attributes with different roles'
    from freeode.interpreter import Interpreter
    from freeode.ast import (DotName, RoleConstant, RoleParameter, 
                             RoleVariable)
    
    prog_text = \
'''
data a: Float const
data b: Float param
data c: Float variable
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
  
    mod = intp.modules['test']
#    print
#    print 'module after interpreter run: ---------------------------------'
#    print mod
    
    a = mod.get_attribute(DotName('a'))
    assert a.role is RoleConstant
    b = mod.get_attribute(DotName('b'))
    assert b.role is RoleParameter
    c = mod.get_attribute(DotName('c'))
    assert c.role is RoleVariable
예제 #10
0
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')
예제 #11
0
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')
def test_interpreter_user_defined_operators_2(): #IGNORE:C01111
    '''
    User defined operators must also work with constant data. 
    Same class as in previous test, but all variables are constant.
    
    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 
    from freeode.ast import DotName, RoleConstant

    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


data a,b,c: Vec1D const
a.x = 2
b.x = 3


#--- invoke the operators ----
c=a+b
'''

    #create the interpreter and interpret the mini-program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    
    mod = intp.modules['test']
    #print
    #print 'Interpreted module: -----------------------------------------------------'
    #print mod
    
    #get the attributes that we have defined
    a = mod.get_attribute(DotName('a'))
    a_x = a.get_attribute(DotName('x'))
    assert a_x.role == RoleConstant
    assert a_x.value == 2
    b = mod.get_attribute(DotName('b'))
    b_x = b.get_attribute(DotName('x'))
    assert b_x.role == RoleConstant
    assert b_x.value == 3
    c = mod.get_attribute(DotName('c'))
    c_x = c.get_attribute(DotName('x'))
    assert c_x.role == RoleConstant
    assert c_x.value == 5
예제 #13
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'
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
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
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
def test_pass_statement_2(): #IGNORE:C01111
    msg = '''
    Test the pass statement. Try stupid but legal cases.
    - The pass statement should just do nothing. 
    '''
    #py.test.skip(msg)
    print msg
    
    from freeode.interpreter import (Interpreter, siml_isinstance, 
                                     CallableObject, TypeObject, IFloat)
    from freeode.ast import DotName

    prog_text = \
'''
#class with definition after pass statement
class A:
    pass
    data x: Float role_unknown

data a:A
a.x = 2

#function with statement after pass statement
func add2(x):
    pass
    return x + 2
    
data four: Float const
four = add2(2)
'''

    #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_A = mod.get_attribute(DotName('A'))
    a = mod.get_attribute(DotName('a'))
    a_x = a.get_attribute(DotName('x'))
    add2 = mod.get_attribute(DotName('add2'))
    four = mod.get_attribute(DotName('four'))
    assert isinstance(class_A, TypeObject)
    assert siml_isinstance(a, class_A)
    assert isinstance(a_x, IFloat)
    assert a_x.value == 2
    assert isinstance(add2, CallableObject)
    assert isinstance(four, IFloat)
    assert four.value == 4
def test_compile_statement__small_simulation_program(): #IGNORE:C01111
    msg = 'Test compile statement: see if small simulation program can be compiled.'
    #py.test.skip(msg)
    print msg
    from freeode.interpreter import Interpreter

    prog_text = \
'''
data g: Float const
g = 9.81


class BarrelWithHole:
    data V, h: Float
    data A_bott, A_o, mu, q: Float param

    func dynamic(this):                            #line 10
        h = V/A_bott
        $V = q - mu*A_o*sqrt(2*g*h)
#        print('h: ', h)

    func initialize(this, q_in):
        V = 0;
        A_bott = 1; A_o = 0.02; mu = 0.55;
        q = q_in #0.05
 
                                                   #line 20
class RunTest:
    data system: BarrelWithHole

    func dynamic(this):
        system.dynamic()

    func initialize(this):
        system.initialize(0.55)
#        solutionParameters.simulationTime = 100
#        solutionParameters.reportingInterval = 1  #line 30

    func final(this):
#        graph(system.V, system.h)
        print('Simulation finished successfully.')
        

compile RunTest
'''

    #create the interpreter
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
def test_function_call_1(): #IGNORE:C01111
    msg = '''Test all legal styles of function calls.'''
    #py.test.skip(msg)
    print msg
    from freeode.interpreter import Interpreter
    from freeode.ast import DotName

    prog_text = \
'''
func foo(a:Float=1, b:Float=2):
    return a + b

data a,b,c,d,e,f,g,h: Float const

a = foo()           # a == 3       - line 7
b = foo(5)          # b = 7
c = foo(5, 6)       # c = 11
d = foo(a=10)       # d = 12       - line 10
e = foo(b=20)       # e = 21
f = foo(5, b=20)    # f = 25
g = foo(a=10, b=20) # g = 30
h = foo(b=20, a=10) # h = 30       - line 14
'''
    #create the interpreter
    intp = Interpreter()
    #run mini program
    intp.interpret_module_string(prog_text, None, 'test')
    
    #get the interpreted module
    mod = intp.modules['test']
#    print
#    print 'module after interpreter run: ---------------------------------'
#    print mod
    
    #test the results
    a = mod.get_attribute(DotName('a'))
    b = mod.get_attribute(DotName('b'))
    c = mod.get_attribute(DotName('c'))
    d = mod.get_attribute(DotName('d'))
    e = mod.get_attribute(DotName('e'))
    f = mod.get_attribute(DotName('f'))
    g = mod.get_attribute(DotName('g'))
    h = mod.get_attribute(DotName('h'))
    assert a.value == 3
    assert b.value == 7
    assert c.value == 11
    assert d.value == 12
    assert e.value == 21
    assert f.value == 25
    assert g.value == 30
    assert h.value == 30
def test_StatementVisitor_assign_emit_code_2(): #IGNORE:C01111
    #py.test.skip('Test interpreter object: emit code without the usual infrastructure.')
    print 'Test StatementVisitor.assign: emit code without the usual infrastructure.'
    from freeode.interpreter import (Interpreter, IFloat)
    from freeode.ast import (Node, NodeAssignment, NodeOpInfix2)

    prog_text = \
'''
data a: Float const
data b: Float variable
data c: Float variable
a = 2*2 #constant no statement emitted
b = 2*a #emit b = 8; compute 2*a at compile time
c = 2*b #emit everything
#print('a = ', a)
#print('b = ', b)
#print('c = ', c)
'''

    #create the interpreter
    intp = Interpreter()
    #enable collection of statements for compilation
    intp.start_collect_code()
    #interpret the program
    intp.interpret_module_string(prog_text, None, 'test')
    #get the results of the collection process
    stmts, func_locals = intp.stop_collect_code()
 
    print
    print '--------------- main module ----------------------------------'
    #print intp.modules['test']
    #put collected statements into Node for pretty printing
    n = Node(statements=stmts)
    print
    print '--------------- collected statements ----------------------------------'
    #print n
        
    assert len(stmts) == 2
    # b = 4
    assert isinstance(stmts[0], NodeAssignment)
    assert isinstance(stmts[0].expression, IFloat) # 8
    assert stmts[0].expression.value == 8
    # c = 2*b
    assert isinstance(stmts[1], NodeAssignment)
    assert isinstance(stmts[1].expression, NodeOpInfix2)        # 2 * b
    assert isinstance(stmts[1].expression.arguments[0], IFloat) # 2
    assert stmts[1].expression.arguments[0].value == 2
    assert isinstance(stmts[1].expression.arguments[1], IFloat) # b
    assert stmts[1].expression.arguments[1].value is None      
def test_interpreter_class_definition_1(): #IGNORE:C01111
    #py.test.skip('Test disabled')
    print 'Test interpreter object: class definition ...............................................................'
    from freeode.interpreter import Interpreter, DotName

    prog_text = \
'''
print('start')

data pi: Float const
pi = 3.1415

class A:
    print('in A definition')
    data a1: Float const
    data a2: Float const

class B:
    data b1: Float const
    b1 = pi
    data b2: Float const

data a: A const
data b: B const

a.a1 = 1
a.a2 = 2 * b.b1
print('a.a1: ', a.a1, ', a.a2: ', a.a2)

print('end')
'''

    #create the interpreter
    intp = Interpreter()
    #interpret the program
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    print 'module after interpreter run: ---------------------------------'
    print intp.modules['test']
  
    assert (intp.modules['test'].get_attribute(DotName('pi')).value == 3.1415)
    assert (intp.modules['test'].get_attribute(DotName('a'))
                                .get_attribute(DotName('a1')).value == 1)
    assert (intp.modules['test'].get_attribute(DotName('a'))
                                .get_attribute(DotName('a2')).value == 2 * 3.1415)
    assert (intp.modules['test'].get_attribute(DotName('b'))
                                .get_attribute(DotName('b1')).value == 3.1415)
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
def test_interpreter_class_definition_2(): #IGNORE:C01111
    '''
    Test user defined classes - correctness of parent attribute.
    
    Data attributes are copied when a class is instantiated. (All attributes
    are constructed when the class is defined.) The parent pointers, which 
    point back to the object that contains each object, must be updated 
    by the copy algorithm.  Otherwise they point to the old parents before the 
    copy.
    
    Interpreter Object has a __deepcopy__ function that takes care of this.
    '''
    #py.test.skip('Test user defined classes - correctness of parent attribute.')
    print 'Test user defined classes - correctness of parent attribute.'
    from freeode.interpreter import (Interpreter, IFloat)
    from freeode.ast import (DotName)

    prog_text = \
'''
class A:
    data z: Float const

class B:
    data a: A const


data b:B const
'''

    #create the interpreter
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    print intp.modules['test']
    
    #get the instance objects defined in this program
    mod = intp.modules['test']
    b = mod.get_attribute(DotName('b'))
    a = b.get_attribute(DotName('a'))
    z = a.get_attribute(DotName('z'))
    
    #check the correctness of the parent attributes
    assert b.parent() is mod
    assert a.parent() is b
    assert z.parent() is a
def test_builtin_function_call_2(): #IGNORE:C01111
    #py.test.skip('Test disabled')
    print 'Test interpreter object: call built in function print...............................................................'
    from freeode.interpreter import Interpreter
    
    prog_text = \
'''
print('test')
'''
    #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']
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
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 == '+'
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
def test_argument_list_compile_statement_1(): #IGNORE:C01111
    msg = '''
    Good error messages when argument 'this' is missing in definition of 
    any main function. ("dynamic()" instead of "dynamic(this)")
    
    This is a reminder for an error (now fixed) where empty argument lists
    did not receive the correct location of their definition.
    
    - The error message should point to line 3 as the line where the function 
    is defined.
    - It should also point to line 6 where the call to dynamic(...) is made 
    implicitly. 
    '''
    #py.test.skip(msg)
    print msg
    
    from freeode.interpreter import Interpreter
    from freeode.ast import UserException

    prog_text = \
'''
class A:
    func dynamic():
        pass
    
compile A
'''

    #interpret the program
    intp = Interpreter()
    try:
        intp.interpret_module_string(prog_text, None, 'test')
    except UserException, e:
        print 'Exception is OK'
        print e
        assert e.errno == 3200250
        print 'Correct exception was raised.'
        #Judge the quality of the error message:
        #Try to find the text 'line 3', which is the line where the function 
        #is defined
        err_str = str(e)
        index = err_str.find('line 3')
        assert index != -1, 'Line of function definition is not mentioned ' \
                            'correctly in error message.'
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
def test_method_call_this_namespace_2(): #IGNORE:C01111
    #py.test.skip('Test interpreter: method call, this namespace')
    print 'Test interpreter: method call, this namespace'
    from freeode.interpreter import Interpreter, DotName

    prog_text = \
'''
class A:
    data a1: Float const
    data a2: Float const
    
    func compute(this, x):
        print('in compute_a2 x=', x)
        a1 = x
        a2 = a1 + 2
        
class B:
    data a: A
    
    func compute(this, x):
        a.compute(x)
    
data b: B const
b.compute(3)
print('b.a.a1 = ', b.a.a1)
print('b.a.a2 = ', b.a.a2)
'''

    #create the interpreter
    intp = Interpreter()
    #interpret the program
    intp.interpret_module_string(prog_text, None, 'test')
  
    print
    print intp.modules['test']
  
    assert (intp.modules['test'].get_attribute(DotName('b'))
                                .get_attribute(DotName('a'))
                                .get_attribute(DotName('a1')).value == 3)
    assert (intp.modules['test'].get_attribute(DotName('b'))
                                .get_attribute(DotName('a'))
                                .get_attribute(DotName('a2')).value == 5)