summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2011-11-30 21:14:48 +0000
committerPeter Wu <lekensteyn@gmail.com>2011-11-30 21:14:48 +0000
commitf8c1ccfac7fc22ba7d316a5b25ee58cd4d26a031 (patch)
tree7c4d17114218fc143eb0b80d0a25554f49c15662
parent4ac454608da0616f4727c10e19161e47570b54db (diff)
downloadpp2cc-f8c1ccfac7fc22ba7d316a5b25ee58cd4d26a031.tar.gz
Support for array reference (both assignment and rvalue), update README
-rw-r--r--README26
-rwxr-xr-xpp2cc.py30
2 files changed, 40 insertions, 16 deletions
diff --git a/README b/README
index 096545f..9521338 100644
--- a/README
+++ b/README
@@ -53,8 +53,8 @@ A7.3 Postfix Expressions - unsupported
function calls - supported, result is stored in register R0 (for int functions)
Other types (void) are not checked when using their value. If an
undefined function is used, it'll still try to branch to the label
- Parameters are not supported.
-A7.4 Unary Operators - supported: ++ -- + - ~ ! Unsupported: sizeof & *
+ Parameters are not supported. Pointers to functions are unsupported
+A7.4 Unary Operators - supported: ++ -- + - ~ ! & * Unsupported: sizeof
A7.5 Casts - unsupported and ignored
A7.6-A7.7, A7.9-7.13 - supported: * / % + - < > <= >= == != & ^ | Left to right
A7.8 Shift - << >> is supported, if the second operand is negative, no shift
@@ -64,7 +64,7 @@ Example in bits assuming 4-bit words: 1000 (-8) >> 2 becomes 0010 (2), 0110 (6)
A7.14-A7.15 Logical AND && and OR || are supported. Result is indeed 0 or 1
A7.16 Conditional operator ? : - supported
A7.17 Assignment - supported: = Unsupported: *= /= %= += -= <<= >>= &= ^= |=
- Supported for variable names only, pointers are not yet supported
+ Supported for variable names only, pointers and array references
A7.18 Comma - supported
A7.19 Constant expressions - not checked
@@ -76,24 +76,30 @@ A8.2 Type specifiers - unsupported, everything is assumed to be int. void in
A8.3 Structure and union declarations - unsupported
A8.4 Enumerations - unsupported
A8.5 Declarators - pointers and qualifiers are ignored, only a direct name is
- supported
-A8.6 Meaning of declarators - pointer is supported, array is not, function is
- supported without parameters and assumed to be an int function
-A8.7 Initialization - Supported for an expression resulting in an int
+ supported. An array can be declared without initialization as in:
+ int a[2];
+A8.6 Meaning of declarators - pointer and arrays are supported, function is
+ supported without parameters and assumed to be an int function.
+A8.7 Initialization - Supported for an expression resulting in an int, arrays
+ may be initialized with a list of expressions yielding a constant
+ value, e.g. int a[2]={3,1+2};int b[]={2}; in If the number of
+ initializers are larger than the dimension, the excess elements are
+ discarded.
+
A8.8 Type names - not verified
A8.9 Typedef - won't be supported as we have int only
A8.10 Type equivalence - not supported as everything is an int
A9 Statements
-A9.1 Labeled statements - not supported
+A9.1 Labeled statements - supported
A9.2 Expression statement - supported by parser
A9.3 Compound statement - supported
A9.4 Selection statements - if and if/else are supported. switch is also
supported including fallthrough and case/ default labels support
A9.5 Iteration statements - while, do/while and for are supported. A missing
second expression in the for is equivalent to a non-zero constant
-A9.6 Jump statements - goto is unsupported. continue and break are supported.
- return is supported with and without value. The function result is
+A9.6 Jump statements - goto, continue and break are supported. return is
+ supported with and without value. The function result is
undefined for the second case
A10 External Declarations
diff --git a/pp2cc.py b/pp2cc.py
index 11ff592..6e6e614 100755
--- a/pp2cc.py
+++ b/pp2cc.py
@@ -1131,8 +1131,12 @@ class Parse(object):
linked_lval = LinkedNode(node.lvalue, linked_node)
# this lvalue may be an expression if there is an indirection
- if isinstance(node.lvalue, c_ast.UnaryOp) and node.lvalue.op == "*":
- lvalue = self.parseExpression(linked_lval.node.expr, linked_lval)
+ if (linked_lval.type == "UnaryOp" and node.lvalue.op == "*" or
+ linked_lval.type == "ArrayRef"):
+ if linked_lval.type == "UnaryOp":
+ lvalue = self.parseExpression(linked_lval.node.expr, linked_lval)
+ else:
+ lvalue = self.parseExpression(linked_lval.node, linked_node)
lvalue_result_reg = self.registers.find_register(lvalue)
for line in lvalue:
# if the right value register is modified, we need to pull
@@ -1186,14 +1190,24 @@ class Parse(object):
linked_type = LinkedNode(linked_node.node.type, linked_node)
var_name = linked_node.variables.declName(linked_node.node.name, 1)
if linked_type.type == "ArrayDecl":
- size = self.determineConstValue(LinkedNode(linked_type.node.dim,
+ if linked_type.node.dim is not None:
+ size = self.determineConstValue(LinkedNode(linked_type.node.dim,
linked_node))
+ else:
+ size = None
node_init = linked_node.node.init
+ # determine the array dimension based on the initializer
if node_init and isinstance(node_init, c_ast.ExprList):
real_size = len(node_init.exprs)
- if real_size > size:
+ if size is None:
+ size = real_size
+ elif real_size > size:
self.logger.warning("excess elements in array initializer",
linked_node=linked_node)
+ # it's an error if the array dimension is unavailable, e.g.:
+ # int a[];
+ if size is None:
+ raise RuntimeError("Array size missing in '{}'".format(var_name))
var_array = linked_node.variables.declName(var_name, size,
prefix="arr")
elif linked_type.type == "PtrDecl":
@@ -1332,8 +1346,12 @@ class Parse(object):
else:
lines += index_expr
- lines.append(self.asm.binary_op("LOAD", name_reg,
- "[" + name_reg + "+" + index_reg + "]"))
+ if (linked_node.parent and linked_node.parent.type == "Assignment" and
+ linked_node.parent.node.lvalue is linked_node.node):
+ lines.append(self.asm.binary_op("ADD", name_reg, index_reg))
+ else:
+ lines.append(self.asm.binary_op("LOAD", name_reg,
+ "[" + name_reg + "+" + index_reg + "]"))
return lines
def parseLabel(self, linked_node):
lines = []