Commit 9bc9d33b authored by dbarbera's avatar dbarbera
Browse files

Added ceil/floor/trunc operators

parent cd6d9b14
......@@ -800,6 +800,12 @@ def _prim_call(prim):
stmts.extend(param_stmts)
local_decl.extend(local_var)
ada_string += ('num_{t}({p})'.format(t=exp_typename, p=param_str))
elif ident == 'floor':
raise NotImplementedError
elif ident == 'ceil':
raise NotImplementedError
elif ident == 'trunc':
raise NotImplementedError
else:
ada_string += '('
# Take all params and join them with commas
......
......@@ -82,6 +82,24 @@ class Context():
[self.double]
)
self.funcs['ceil'] = core.Function.intrinsic(
self.module,
core.INTR_CEIL,
[self.double]
)
self.funcs['floor'] = core.Function.intrinsic(
self.module,
core.INTR_FLOOR,
[self.double]
)
self.funcs['trunc'] = core.Function.intrinsic(
self.module,
core.INTR_TRUNC,
[self.double]
)
self.funcs['fabs'] = core.Function.intrinsic(
self.module,
core.INTR_FABS,
......@@ -1271,20 +1289,26 @@ def _prim_call(prim, ctx):
args = prim.value[1]['procParams']
arg_vals = [expression(arg, ctx) for arg in args]
if name == 'length':
return sdl_length(arg_vals[0], args[0].exprType, ctx)
elif name == 'present':
return sdl_present(arg_vals[0], ctx)
elif name == 'abs':
if name == 'abs':
return sdl_abs(arg_vals[0], ctx)
elif name == 'ceil':
return sdl_ceil(arg_vals[0], ctx)
elif name == 'fix':
return sdl_fix(arg_vals[0], ctx)
elif name == 'float':
return sdl_float(arg_vals[0], ctx)
elif name == 'power':
return sdl_power(arg_vals[0], arg_vals[1], ctx)
elif name == 'floor':
return sdl_floor(arg_vals[0], ctx)
elif name == 'length':
return sdl_length(arg_vals[0], args[0].exprType, ctx)
elif name == 'num':
return sdl_num(arg_vals[0], ctx)
elif name == 'power':
return sdl_power(arg_vals[0], arg_vals[1], ctx)
elif name == 'present':
return sdl_present(arg_vals[0], ctx)
elif name == 'trunc':
return sdl_trunc(arg_vals[0], ctx)
raise CompileError('Unknown operator %s' % name)
......@@ -1806,7 +1830,7 @@ def sdl_present(s_ptr, ctx):
def sdl_abs(x_val, ctx):
''' Generate the IR for a abs operation '''
''' Generate the IR for an abs operation '''
if x_val.type.kind == core.TYPE_INTEGER:
expr_conv = ctx.builder.sitofp(x_val, ctx.double)
res_val = sdl_call('fabs', [expr_conv], ctx)
......@@ -1815,6 +1839,21 @@ def sdl_abs(x_val, ctx):
return sdl_call('fabs', [x_val], ctx)
def sdl_floor(x_val, ctx):
''' Generate the IR for a floor operation '''
return sdl_call('floor', [x_val], ctx)
def sdl_ceil(x_val, ctx):
''' Generate the IR for a ceil operation '''
return sdl_call('ceil', [x_val], ctx)
def sdl_trunc(x_val, ctx):
''' Generate the IR for a cos operation '''
return sdl_call('trunc', [x_val], ctx)
def sdl_fix(x_val, ctx):
''' Generate the IR for a fix operation '''
return ctx.builder.fptosi(x_val, ctx.i64)
......
......@@ -28,6 +28,7 @@ __author__ = 'Maxime Perrotin'
import sys
import os
import math
import logging
import traceback
from itertools import chain, permutations, combinations
......@@ -101,17 +102,22 @@ ENUMERATED = type('EnumeratedType', (object,), {'kind': 'EnumeratedType'})
UNKNOWN_TYPE = type('UnknownType', (object,), {'kind': 'UnknownType'})
SPECIAL_OPERATORS = {
'abs': [{'type': NUMERICAL, 'direction': 'in'}],
'ceil': [{'type': REAL, 'direction': 'in'}],
'fix': [{'type': NUMERICAL, 'direction': 'in'}],
'float': [{'type': NUMERICAL, 'direction': 'in'}],
'floor': [{'type': REAL, 'direction': 'in'}],
'length': [{'type': LIST, 'direction': 'in'}],
'write': [{'type': ANY_TYPE, 'direction': 'in'}],
'writeln': [{'type': ANY_TYPE, 'direction': 'in'}],
'num': [{'type': ENUMERATED, 'direction': 'in'}],
'power': [{'type': NUMERICAL, 'direction': 'in'},
{'type': INTEGER, 'direction': 'in'}],
'present': [{'type': CHOICE, 'direction': 'in'}],
'set_timer': [{'type': INTEGER, 'direction': 'in'}, {'type': TIMER, 'direction': 'in'}],
'reset_timer': [{'type': TIMER, 'direction': 'in'}],
'abs': [{'type': NUMERICAL, 'direction': 'in'}],
'num': [{'type': ENUMERATED, 'direction': 'in'}],
'float': [{'type': NUMERICAL, 'direction': 'in'}],
'fix': [{'type': NUMERICAL, 'direction': 'in'}],
'power': [{'type': NUMERICAL, 'direction': 'in'}, {'type': INTEGER, 'direction': 'in'}]
'set_timer': [{'type': INTEGER, 'direction': 'in'},
{'type': TIMER, 'direction': 'in'}],
'trunc': [{'type': REAL, 'direction': 'in'}],
'write': [{'type': ANY_TYPE, 'direction': 'in'}],
'writeln': [{'type': ANY_TYPE, 'direction': 'in'}],
}
# Container to keep a list of types mapped from ANTLR Tokens
......@@ -1312,20 +1318,32 @@ def primary_call(root, context):
'Max': str(max(float(param_btys[0].Max), 0))
})
elif name == 'ceil':
node.exprType = type('Ceil', (REAL,), {
'Min': str(math.ceil(float(param_btys[0].Min))),
'Max': str(math.ceil(float(param_btys[0].Max)))
})
elif name == 'fix':
node.exprType = type('fix', (INTEGER,), {
node.exprType = type('Fix', (INTEGER,), {
'Min': param_btys[0].Min,
'Max': param_btys[0].Max
})
elif name == 'float':
node.exprType = type('float', (REAL,), {
node.exprType = type('Float', (REAL,), {
'Min': param_btys[0].Min,
'Max': param_btys[0].Max
})
elif name == 'floor':
node.exprType = type('Floor', (REAL,), {
'Min': str(math.floor(float(param_btys[0].Min))),
'Max': str(math.floor(float(param_btys[0].Max)))
})
elif name == 'length':
node.exprType = type('length', (INTEGER,), {
node.exprType = type('Length', (INTEGER,), {
'Min': param_btys[0].Min,
'Max': param_btys[0].Max
})
......@@ -1348,11 +1366,17 @@ def primary_call(root, context):
})
elif name == 'present':
node.exprType = type('present', (object,), {
node.exprType = type('Present', (object,), {
'kind': 'ChoiceEnumeratedType',
'EnumValues': param_btys[0].Children
})
elif name == 'trunc':
node.exprType = type('Trunc', (REAL,), {
'Min': str(math.trunc(float(param_btys[0].Min))),
'Max': str(math.trunc(float(param_btys[0].Max)))
})
except TypeError as err:
errors.append(error(root, str(err)))
except OverflowError:
......
......@@ -22,23 +22,29 @@ DCL c Choice := i:2;
CALL assert(abs(-i) = i, 'abs(-i) = i');
/* CIF PROCEDURECALL (-8, 274), (264, 35) */
CALL assert(abs(-f) = f, 'abs(-f) = f');
/* CIF PROCEDURECALL (12, 324), (224, 35) */
/* CIF PROCEDURECALL (-22, 324), (293, 35) */
CALL assert(ceil(f + 0.5) = 3.0, 'ceil(f + 0.5) = 3.0');
/* CIF PROCEDURECALL (12, 374), (224, 35) */
CALL assert(fix(f) = i, 'fix(f) = i');
/* CIF PROCEDURECALL (-1, 374), (251, 35) */
/* CIF PROCEDURECALL (-1, 424), (251, 35) */
CALL assert(float(i) = f, 'float(i) = f');
/* CIF PROCEDURECALL (-47, 424), (343, 35) */
/* CIF PROCEDURECALL (-18, 474), (284, 35) */
CALL assert(floor(f + 0.5) = f, 'floor(f + 0.5) = f');
/* CIF PROCEDURECALL (-47, 524), (343, 35) */
CALL assert(length(fixSeqOf) = 3, 'length(fixSeqOf) = 3');
/* CIF PROCEDURECALL (-51, 474), (350, 35) */
/* CIF PROCEDURECALL (-51, 574), (350, 35) */
CALL assert(length(varSeqOf) = 3, 'length(varSeqOf) = 3');
/* CIF PROCEDURECALL (3, 524), (240, 35) */
/* CIF PROCEDURECALL (3, 624), (240, 35) */
CALL assert(num(e) = 12, 'num(e) = 12');
/* CIF PROCEDURECALL (-14, 574), (276, 35) */
/* CIF PROCEDURECALL (-14, 674), (276, 35) */
CALL assert(power(i, 3) = 8, 'power(i, 3) = 8');
/* CIF PROCEDURECALL (24, 624), (200, 35) */
/* CIF PROCEDURECALL (-26, 724), (301, 35) */
CALL assert(trunc(f + 0.1) = f, 'trunc(f + 0.1) = f');
/* CIF PROCEDURECALL (24, 774), (200, 35) */
CALL writeln(i, f, b, s);
/* CIF PROCEDURECALL (24, 674), (200, 35) */
/* CIF PROCEDURECALL (24, 824), (200, 35) */
CALL write(i, f, b, s);
/* CIF NEXTSTATE (74, 724), (100, 50) */
/* CIF NEXTSTATE (74, 874), (100, 50) */
NEXTSTATE Wait;
ENDSTATE;
ENDPROCESS operators;
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment