Commit 16032e15 authored by dbarbera's avatar dbarbera
Browse files

Raise compile error for unexpected cases in bitwise/shortcircuit expressions

parent 87bc8ba6
......@@ -307,6 +307,10 @@ class Scope:
return label_block
class CompileError(Exception):
pass
@singledispatch
def generate(ast):
''' Generate the code for an item of the AST '''
......@@ -1075,7 +1079,13 @@ def generate_assign(left, right):
@expression.register(ogAST.ExprXor)
def _logic(expr):
''' Generate the code for a logic expression '''
bty = find_basic_type(expr.exprType)
if expr.shortcircuit:
if bty.kind != 'BooleanType':
raise CompileError('Type "%s" not supported in shortcircuit expressions'
% bty.kind)
func = ctx.builder.basic_block.function
right_block = func.append_basic_block('')
......@@ -1090,7 +1100,7 @@ def _logic(expr):
elif expr.operand == 'or':
ctx.builder.cbranch(left_val, end_block, right_block)
else:
raise NotImplementedError
raise CompileError('Unknown shortcircuit operator "%s"' % expr.operand)
ctx.builder.position_at_end(right_block)
right_val = expression(expr.right)
......@@ -1100,18 +1110,16 @@ def _logic(expr):
ctx.builder.position_at_end(end_block)
return ctx.builder.load(res_ptr)
else:
bty = find_basic_type(expr.exprType)
if bty.kind == 'BooleanType':
elif bty.kind == 'BooleanType':
left_val = expression(expr.left)
right_val = expression(expr.right)
if expr.operand == 'and':
return ctx.builder.and_(left_val, right_val)
elif expr.operand == 'or':
return ctx.builder.or_(left_val, right_val)
else:
elif expr.operand == 'xor':
return ctx.builder.xor(left_val, right_val)
raise CompileError('Unknown bitwise operator "%s"' % expr.operand)
elif bty.kind == 'SequenceOfType' and bty.Min == bty.Max:
func = ctx.builder.basic_block.function
......@@ -1146,8 +1154,10 @@ def _logic(expr):
res_elem_val = ctx.builder.and_(left_elem_val, right_elem_val)
elif expr.operand == 'or':
res_elem_val = ctx.builder.or_(left_elem_val, right_elem_val)
else:
elif expr.operand == 'xor':
res_elem_val = ctx.builder.xor(left_elem_val, right_elem_val)
else:
raise CompileError('Unknown bitwise operator "%s"' % expr.operand)
res_elem_ptr = ctx.builder.gep(res_ptr, [ctx.zero, ctx.zero, idx_val])
ctx.builder.store(res_elem_val, res_elem_ptr)
......@@ -1165,8 +1175,7 @@ def _logic(expr):
ctx.builder.position_at_end(end_block)
return res_ptr
else:
raise NotImplementedError
raise CompileError('Type "%s" not supported in bitwise expressions' % bty.kind)
@expression.register(ogAST.ExprNot)
......@@ -1177,7 +1186,7 @@ def _not(expr):
if bty.kind == 'BooleanType':
return ctx.builder.not_(expression(expr.expr))
elif bty.kind == 'SequenceOfType':
elif bty.kind == 'SequenceOfType' and bty.Min == bty.Max:
func = ctx.builder.basic_block.function
not_block = func.append_basic_block('not:not')
......@@ -1190,12 +1199,6 @@ def _not(expr):
struct_ptr = expression(expr.expr)
res_struct_ptr = ctx.builder.alloca(struct_ptr.type.pointee)
if bty.Min != bty.Max:
len_ptr = ctx.builder.gep(struct_ptr, [ctx.zero, ctx.zero])
len_val = ctx.builder.load(len_ptr)
res_len_ptr = ctx.builder.gep(res_struct_ptr, [ctx.zero, ctx.zero])
ctx.builder.store(len_val, res_len_ptr)
else:
array_ty = struct_ptr.type.pointee.elements[0]
len_val = core.Constant.int(ctx.i32, array_ty.count)
......@@ -1204,9 +1207,6 @@ def _not(expr):
ctx.builder.position_at_end(not_block)
idx_val = ctx.builder.load(idx_ptr)
if bty.Min != bty.Max:
elem_idxs = [ctx.zero, ctx.one, idx_val]
else:
elem_idxs = [ctx.zero, ctx.zero, idx_val]
elem_ptr = ctx.builder.gep(struct_ptr, elem_idxs)
......@@ -1226,8 +1226,7 @@ def _not(expr):
ctx.builder.position_at_end(end_block)
return res_struct_ptr
else:
raise NotImplementedError
raise CompileError('Type "%s" not supported in bitwise expressions' % bty.kind)
@expression.register(ogAST.ExprAppend)
......
Supports Markdown
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