| 6 | | * introduce LHSExpression, a subtype of Expression: DONE |
| 7 | | * rename !ArrayIndexExpression to !SubscriptExpression: DONE |
| 8 | | * modify !ModelBuilder to get rid of arrow expressions, replacing them with dot of star: DONE |
| 9 | | * modify !ModelBuilder to get rid of C's pointer-array pun: |
| 10 | | * in any subscript expression `a[i]`, make sure `a` has array type. If it doesn't, translate to `*(a+i)` : DONE |
| 11 | | * in any place where a pointer is called for, but instead an array `a` is used, replace `a` with `&a[0]`. Examples include pointer arithmetic (`a+i`, `a-b`), argument to dereference operator `*`, actual arguments in function calls where the corresponding parameter has pointer type. : DONE |
| 12 | | * make sure the parameter type of a function call is never an array type. ABC should already be doing this. |
| 13 | | * use an enumerated type like !ExpressionKind for the different kinds of expressions, so `switch` statements can be used: DONE |
| | 6 | * make sure the parameter type of a function call is never an array type. ABC should already be doing this. |
| 15 | | |
| | 8 | * add a new `CIVLType`: `CIVLDynamicType.` |
| | 9 | * A CIVL Expression of that type, when evaluated, will yield a `SymbolicExpression` `x`. A method in the `Evaluator`, `SymbolicType getSymbolicType(SymbolicExpression x);`, will take such an `x` and return a `SymbolicType` and that is basically the only operation that can be performed on `x`. Hence this gives you a way to take a (dynamic, symbolic) type and wrap it up into a value that can be stored in a variable in your model. |
| | 10 | * add a new kind of CIVL `Expression`: `DynamicTypeOf(t)`, where `t` is a (static) CIVL type. |
| | 11 | * The type of this expression is `CIVLDynamicType`. When evaluated, it returns the dynamic type determined by the current state and the given static type. (This assumes extent expressions are stored in array types.) For example, if `t` is the static type `struct foo { double a[n]; }` from the source code above, then `DynamicTypeOf(t)`, evaluated in the state that arises at that point in the source code, will yield the symbolic type which is a record type with one field which is an array of doubles of length 2. Now you can store that dynamic type in a variable if you want to save it, e.g., insert a statement like this into the model: |
| | 12 | * `CIVLDynamicType __struct_foo__ = DynamicTypeOf(struct foo { double a[n]; });` |
| | 13 | * add a new kind of CIVL expression: `InitialValue[variable, dynamicType]`. Here, `variable` is a (static) `Variable`, and `dynamicType` is an expression of type `CIVLDynamicType`. The type of this expression is the type of the variable. When evaluated, it returns a default initial value for a variable with the given dynamic type. This can be used to initialize arrays and structs. |
| | 14 | * add a new `CIVLType`: `CIVLScopeType` |
| | 15 | * add new subtype of `Variable`: `CIVLScopeVariable` with method |
| | 16 | * `Scope getScope();` |
| | 17 | * add to the CIVL pointer type a method to get the scope variable, implement appropriate constructors and modifications to the factory, etc. |
| 21 | | * don't use !Vector. Use !LinkedList if you only need to iterate; use !ArrayList if you need constant time access |
| 22 | | * !processType, etc: for these and other fields, make them canonic using !universe.canonic(…)!. This can improve efficiency. DONE |
| 23 | | * never return !null if a case is not handled. Instead throw an appropriate exception: DONE |
| 24 | | * use !switch instead of big if...else if… sequence "mostly DONE" |
| 25 | | * evaluation of dot expression should be simply `return universe.tupleRead(evaluate(expr.struct()…), expr.index())` or something like that: DONE |
| 26 | | * evaluation of !SubscriptExpression should be simply `return universe.arrayRead(evaluate(expr.array()…), evaluate(expr.index()…))` or something like that: DONE |
| 27 | | * evaluate of `NOT_EQUAL`: use `universe.neq()`: DONE |
| 28 | | * implement pointer addition and subtraction. [addition DONE, subtraction coming] |
| 29 | | * implement string literals using `universe.stringExpression()` (it returns an array of char). DONE? |
| 30 | | * references: re-do to use new (upcoming) methods in symbolic universe to create a reference to a point within a symbolic expression. this will eliminate the need to deal with navigation sequences. You still need to figure out the variable, scope and model IDs. DONE |
| 31 | | * use a tuple with one integer field for scope IDs instead of symbolic constants. DONE |
| 32 | | * don't do any string manipulation or parsing dynamically, if possible: DONE |
| 33 | | * `evaluate(…VariableExpression)`: the error reporting code for incorporating the state into the log entry seems general enough that you could factor it out into a separate method somewhere to re-use every time there is an error to report (maybe in Log?) : DONE (state exceptions) |
| 34 | | * construct and set the heap type in the constructor for !Evaluator, just like the other special types |
| | 23 | * don't use `Vector`. Use `LinkedList` if you only need to iterate; use `ArrayList` if you need constant time access |
| | 24 | * use `switch` instead of big `if...else if…` sequence (mostly DONE) |
| | 25 | * implement pointer subtraction |
| | 26 | * construct and set the heap type in the constructor for `Evaluator`, just like the other special types |