Changes between Initial Version and Version 1 of PIL


Ignore:
Timestamp:
10/02/24 21:07:27 (20 months ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PIL

    v1 v1  
     1= PIL: Parallel Intermediate Language
     2
     3== Basic Properties
     4* PIL programs are target of translators from C, Fortran, MPI/OpenMP/etc. They can also be written by humans.
     5* PIL should be a high-level language like CIVL-C.
     6* PIL programs can be easily translated to PFG.
     7* PIL must also have a totally well-defined semantics and syntax.
     8* PIL programs can have nested funtion definitions.
     9* PIL programs can use preprocessor directives like in C
     10* There are no automatic conversions.  All must be done by explicit casts.
     11* `$input`/`$output` variables in global scope (like CIVL-C)
     12* Identifiers are like in C, e.g.,  `x`, `f10`, ...
     13* Keywords, functions, etc. not in C start with `$` (like CIVL-C)
     14* Libraries: similar to C, `#include <stdlib.h>`, but these name PIL libraries and there are additional PIL libraries
     15* PIL programs can be divided into multiple files (translation units)
     16 *  One TU can refer to a variable, function, type, in another TU.
     17 * the variable just needs to be declared somewhere in the TU
     18 * the function just needs a prototype somewhere in the TU
     19 * the use of "static" in a variable decl or function def makes it private to that TU (so two can have same name)
     20 * no need for "extern"
     21 * at most one of the TUs declaring the variable can have an initializer
     22 * at most one of the TUs can have a definition for a function
     23* Program order:
     24 * a program is a sequence of variable, function, and type definitions.
     25 * the order is totally irrelevant.
     26 * a variable can be used anywhere it is in scope
     27 * a function can be called anywhere it is in scope
     28
     29== Types
     30- type names look like `int[]`, `int*[](double)`, etc.
     31- basic types: same as C: `_Bool`, `char`, `short`, `int`, `long`, `long long`, `unsigned`, `float`, `double`, ...
     32- what are the limits of these types?  to be decided
     33- `$int`, `$real` (mathematical types)
     34- `struct`: as in C
     35- `union`: as in C
     36- `T[]`: sequence of `T`.  Note: no "T[n]".  sequences can be assigned, returned, passed as arguments, etc. 
     37- `$set<T>` : finite set of `T`, ops to add, contains, remove, size, ...
     38- `$map<T1,T2>` : finite map from `T1` to `T2`, ops to put, get, containsKey, ...
     39- `$fun<T1,T2>` : total functions from `T1` to `T2`
     40- `$tuple<T,...>` : tuples of specified type (similar to struct)
     41- `$rel<T,...>` : relations of specified type (set of tuples)
     42- `T*`: pointer to `T`
     43 -   what can be pointed to: var, array element, struct element, union member,  ...
     44- Type definitions: `typedef typename ID;`
     45
     46== Tuples
     47
     48Non-mutating expressions:
     49- `t1 == t2`
     50- `t.i`
     51- `($tuple<T1,...>){ x1, ... }`
     52- `$pure $tuple<T1,...> $tuple_write($tuple<T1,...> t, $int i, Ti x);`
     53
     54Mutating expressions:
     55- `t.i = x;`
     56
     57== Sets
     58
     59Non-mutating expressions:
     60- `s1 == s2`
     61- `($set<T>)$empty`   // empty set of type T
     62- `$pure _Bool $set_in(T x, $set<T> s);`  // is x an element of s?
     63
     64  $pure $set<T> $set_with($set<T> s, T x); // s U {x}
     65  $pure $set<T> $set_without($set<T> s, T x); // s - {x}
     66  $pure $set<T> $set_union($set<T> s1, $set<T> s2); // s1 U s2
     67  $pure $set<T> $set_difference($set<T> s1, $set<T> s2); // s1-s2
     68  $pure $set_intersection($set<T> s1, $set<T> s2); // s1 \cap s2
     69  $pure T[] $set_elements($set<T> s);
     70  $pure _Bool $set_isSubsetOf($set<T> s1, $set<T> s2);
     71  $pure $set<U> $set_map($set<T> s, $fun<T,U> f);
     72
     73
     74  Mutation functions:
     75  _Bool $set_add($set<T> * this, T x);
     76  _Bool $set_remove($set<T> * this, T x);
     77  void $set_addAll($set<T> * this, $set<T> that);
     78  void $set_removeAll($set<T> * this, $set<T> that);
     79  void $set_keepOnly($set<T> * this, $set<T> that);
     80
     81  Sequences (arrays)
     82  =========
     83  Expressions:
     84  a1 == a2
     85  a[i]
     86  (T[]){ x1, ... }
     87 
     88  Built-in logic functions:
     89  $pure T[] $seq_fun($int len, $fun<$int,T> f);
     90  $pure T[] $seq_uniform($int n, T val);
     91  $pure $int $length(T[] a); // length of a
     92  $pure T[] $seq_write(T[] a, int i, T x);  // a[i:=x]
     93  $pure T[] $seq_subseq(T[] a, int i, int n);  // a[i..i+n-1]
     94  $pure T[] $seq_without(T[] a, int i); // a with position i removed
     95  $pure T[] $seq_with(T[] a, int i, T x);
     96  $pure T[] $seq_concat(T[] a1, T[] a2);
     97  $pure U[] $seq_map(T[] a, $fun<T,U> f);
     98  $pure T[] $seq_filter(T[] a, $fun<T,_Bool> f);
     99  $pure U $seq_foldl(T[] a, $fun<$tuple<T,U>,U> f, U init);
     100  $pure U $seq_foldr(T[] a, $fun<$tuple<T,U>,U> f, U init);
     101
     102  Mutating operations:
     103  a[i]=x;
     104
     105  Mutating Procedures:
     106  T $seq_remove(T[] * this, int i);
     107  void $seq_insert(T[] * this, int i, T x);
     108  void $seq_append(T[] * this, T[] that);
     109
     110  Maps
     111  ====
     112  Non-mutation:
     113  m1 == m2
     114  ($map<K,V>)$empty
     115  $pure V $map_get($map<K,V> K key);
     116  $pure _Bool $map_containsKey($map<K,V> map, K key);
     117  $pure _Bool $map_containsValue($map<K,V> map, V val);
     118  $pure $map<K,V> $map_with($map<K,V> map, K key, V val);
     119  $pure $map<K,V> $map_without($map<K,V> map, K key);
     120  $pure $set<K> $map_keys($map<K,V> map);
     121  $pure $set<$tuple<K,V>> $map_entries($map<K,V> map);
     122
     123  Mutation:
     124  V $map_put($map<K,V> * this, K key, V val);
     125  V $map_remove($map<K,V> * this, K key);
     126  void $map_removeAll($map<K,V> * this, $set<K> keys);
     127  void $map_addAll($map<K,V> * this, $map<K,V> that);
     128
     129  Functions
     130  =========
     131  There are two kinds of functions in PIL:
     132 
     133  1. (Imperative) procedures, like in C.  These can be nested.
     134     Obviously they can have side-effects, be nondeterministic, and
     135     the behavior can depend on non-local state.  A procedure call
     136     f(x1,...,xn) is an expression that can be used anywhere an
     137     expression with side-effects is allowed.  Imperative procedures
     138     are not values and cannot be assigned to anything.  However, as
     139     in C, a pointer to a procedure is a first-class value that can be
     140     assigned, used as an argument, returned, etc.   There is a
     141     procedure type, exactly like C's function type, e.g.,
     142
     143       typedef int(int) i2i;
     144
     145     defines i2i to be the type "procedure consuming int and returning
     146     int".  Most commonly, pointers to procedure types will be used,
     147     e.g.,
     148
     149       typedef int(int)* i2ip;
     150
     151     defines the type "pointer to procedure from int to int".  As in
     152     C, a pointer to a procedure can be used in a procedure call.
     153
     154     A procedure definition can be templated:
     155     
     156       <T1,T2,...> <procedure def>
     157       
     158     This defines one procedure for each assignment of types to
     159     the Ti.
     160     
     161  2. Logic functions.  Typically specified by a $lambda expression.
     162     These are first-class objects in PIL: they can be assigned to
     163     variables, passed as an argument in a function call (including a
     164     procedure call), and can be returned by a function.  Each has a
     165     type of the form $fun<T1,...,Tn;U> (functions from T1 x...x Tn to
     166     U).  They are side-effect-free.  An application of a logic
     167     function f(x1,...,xn) is an expression that can be used anywhere
     168     an expression is allowed.  A logic function is not necessarily
     169     pure, i.e., the value of an application may depend on any part of
     170     the state, not just the arguments.
     171 
     172  Lambda expressions: have the form
     173
     174  $lambda (T1 x1, ..., Tn xn) {U1 v1=init1; ... Um vm=initm; expr}
     175
     176  where the Ti and Uj are types, the xi and vj are variables,
     177  and expr is an expression in which the only variables that can
     178  occur free are the x1,..., xn, v1,..., vm.  The initializer
     179  expressions initj are expressions using any variables in scope.
     180  The expression has type $fun<T1,...,Tn; V>, where V is the type
     181  of expr.
     182
     183  Semantics: the lambda expression is evaluated to yield a *closure*:
     184  an ordered pair consisting of a dyscope and an expression.  The
     185  dyscope has variables v1, ..., vm, initialized by evaluating init1,
     186  ..., initm.  The dyscope has no parent scope, it is associated only
     187  with the closure.  The expression is expr.  The dyscope is destroyed
     188  whenever it becomes unreachable, i.e., whenever no part of the state
     189  is assigned the closure.
     190
     191  A logic function application f(e1,...,en) is evaluated by first
     192  evaluating the arguments ei, then assigning the ei to the xi and
     193  evaluating expr in the closure dyscope.  Note that since expr
     194  has no side effects, the values of the xi are constant.
     195  [Note: a possible change is to allow side-effects in logic
     196  functions.]
     197
     198Heaps
     199=====
     200
     201  There is a single heap for dynamic allocation.  The following
     202  built-in procedures are provided:
     203 
     204  T* $new<T>(): creates an object A of type T in heap and returns &A.
     205
     206  T* $alloc<T>(int n): creates an array A of length n of T in heap and
     207  returns &A[0].
     208
     209  [Question: how to model C's malloc?   Must be able to execute it
     210  without knowing T.]
     211
     212  void $free<T>(T* p): frees the object referred to by p, the
     213  pointer returned by an earlier call to $new or $alloc.
     214
     215
     216Questions
     217  how to deal with "undefined" values?
     218 
     219  can there be nondeterministic expressions, i.e., expressions that
     220  evaluate to a set of values instead of one value?
     221
     222  how to implement C's malloc?
     223
     224Union of all types occurring in program:
     225typedef union {
     226  T1 t1;
     227  T2 t2;
     228  ...
     229} BigUnion;
     230
     231
     232A call to malloc returns a memory block:
     233  - size (in bytes) (int)
     234  - num_elements (int)
     235  - sequence of tuples:
     236    - offset (int)
     237    - size (int)
     238    - value (type BigUnion)