Inf / SPS

SPS = SimpleProceduralSemantics

  • only two addressing levels:
    • constants & defined functions
    • local data of a function activation (stack)
  • expressions and statements are the same
  • restricted visibilty: we cannot make methods so small, simple syntax is ok
  • multi assignement [a,c,d] = e(e,e) ==> that is not really simple?

Universe

U = Bool ∪ Int (with 0 ∈ Int ⊆ Integer) ∪ Subset of String ∪ Map (code is implemented by maps) ∪ {null, dy, ...}

  • a finite or infinite set of immutable base objects, including Bool {true, false} a subset of int including 0, 1, .., characters and strings
  • a finite or infinite set of map ids. Each mapId yields a mutabe partial map U → U. maps may be restricted to the number of entries (>= 2) of wh
  • kann man partial maps einfach durch totale Funktionen ersetzen? ja mit constante undef
    • am besten als constante mapId mit U → undef (immer new == undef, nie new is undef)
  • wie einfachen übergang zu weniger BaseObjects, z.B. implementieren von Strings durch maps: Int→Char ?
  • Gleichheit is selbe MapId, '==' selbe key→value pairs
  • type: Map: currenttype info ???
  • maps can be frozen (made readonly)
  • during a for loop over a map, the keys read only (remove/add of keys disallowed, however values of existing keys may be changed)

Map

  • U → U
  • ∈ binary op: key is in map
  • [ ] binary op get
  • size: unary op Map → Int
  • for k:v in e do e
  • put value at key
  • remove key
  • new new(e) empty Map
  • type: U → U type function (Bool, Int, codeIf, codeAss ...
  • syntax for structured data: [ (c : e ; | e = e ;)* ]

Environment

  • local: current activation map. local is accessible only within functions, it is read&write - it is the map a function is called with
  • global: global is accessible everywhere, but within functions only readonly - maps are transitively readonly
  • execution of dy will halt the program immediately in error state

Syntax minimal - for virtual machine

e =

  • stringConst
  • numConst
  • local | global | true | false | undef | new | dy
  • e [ e ]
    • map m hasKey k is coded as m[k] is undef
    • as a key undef works as any other element of universe: m[undef] may yield any u ∈ U
  • e [ e = e ]
    • remove key k from map m is coded as m[k=undef]
  • fun e endFun
  • return e
  • e ( e )
  • if e then e else e endIf
  • while e do e endWhile
  • for a (: a)? in e do e endFor
  • ( e )
  • e ; e
  • op e | e op e | e op
  • op operands
    • l is r: identity on map(Ids), equality of contents on base values
    • l == r: equality of (current) values: ∀ u∈U: l[u] is r[u]
    • and, or, not: usual boolean operands, dy if the operands are not boolean
    • +, -, *, **, /, //, % usual ops on Int, dy if the operands are not numeric, overflow, division by zero, etc.
    • <, <= comparision on Bool (true > false), int, works on U×U → Bool, depends on MapIds not the values, with the usual laws (transitive, <= is (< or ==) etc.)

code samples

  • new['eins' = 1]['zwei' = 2] ---> new map with two keys
  • brauchen wir explizites encoding code → Map? entweder das, oder code muss ins Universum aufgenommen werden ....
    • fun yields a read only map that may be execute (by e(e)), the layout is unspecified

Syntax sugared

  • identifiers: in functioni, if assigned to (here or before) then local, otherwise global
    • Achtung indentifiers links vom assignment bezeichnen direkt eine Adresse, rechts aber den dort gespeicherten Wert!
      • a = b ==> put(local, 'a', local['b']]
      • a!!'' = b ==> put(local, local['a'], local['b']]
    • Variationen
      • Deklaration sagt ob ident zu local, global, oder wo auch immer hingehört
      • nicht Deklariert, aber Umgebung sagt es: in Funktion local, innerhalb von map[ .... ] map usw.
      • address construct: (map, key)
      • a.b[c] = e Konstrukt ist natürlich weil nächste Auswertung von a.b[c] eben e ergibt und man kann den Unterschied von linker und rechter Seite eigentlich vergessen
      • a.b[c=d, e=f] ist Abkürzung für a.b.c=d;a.b.e=f. kein Umgebungswechsel für Variabeln!
      • aber was bedeutet a[b=(c=d)]? ==> a.b=(a.c=d) also einfach map prefix vor leftParts of assginment.
      • a[c=d, e[f=g]: local.a.e.f oder local.e.f ==> nach map Prefix Regel das erste! spezialRegel für local und global: sind kein varId's, können also auch nicht prefixed werden (oder sogar prefix char? ==> nö bräuchte merhstufigen .....)
      • a[....] prefixed nur assLeftpart, with a do e oder fun.... endFun () ändert local (oder with nur präfix und kann doch aufs äussere local zugreifen?)
      • a[e=e] und a[e] sind ganz verschieden, wegen rekursiven definition von e mehrdeutig
      • , für embedded ass in [ ], ; für statements oder ist das überflüssig?
  • updMap: current map for updates ????
  • call with formal/actual parameters
  • easy map/structure creation
    • t1 , t2 ⇒ ( t1 ) t2
    • .id ⇒ ['id']

constants and especially named functions, are visible

  1. after the declaration in the current scope
  2. also in nested functions (from the current scope)

variables are visible

  1. after the declaration in the current scope
  2. not in nested functions
  3. but only in other nested scopes ( {}. if, while, ...)

e =

  • const newName = e
  • forward newName+ * ersetzen durch limited 2 phase compile?
  • fun (newName as)? e endFun
  • return e
  • var newName (, newName)* = e
  • name
  • e . id
  • e [ e ]
  • e e
  • name = e
  • e : e
  • delete e
  • (update e)? [ e? ]
  • ( e )
  • e ; e
  • op e | e op e | e op
  • e ( e? ) --- without unnested assignments then e yields map else new map with these unnested assignments
  • if e (then e)? (elif e (then e)? )* (else e)? endIf
  • while e do e endWhile
  • for name (: name) in e do e endFor
  • actMap: current activation map for get for update if not within an update expressio
  • outerMap: readonly outer block
  • updMap: current map for updates

constants and especially named functions, are visible

  1. after the declaration in the current scope
  2. also in nested functions (from the current scope)

variables are visible

  1. after the declaration in the current scope
  2. not in nested functions
  3. but only in other nested scopes ( {}. if, while, ...)

datastructures

  • implizit/explizit references
  • single valued / optional / multivalued atts
  • a, b, c ⇒ record fields
  • o → o: ⇒ map