Next: , Previous: , Up: TC-3   [Contents][Index]


4.5.2 TC-3 Samples

Binding is relating a name use to its definition.

let
  var me := 0
in
  me
end

File 4.18: me.tig

$ tc -XbBA me.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x563048f78b00 */() =
  (
    let
      var me /* 0x563048f7b5b0 */ := 0
    in
      me /* 0x563048f7b5b0 */
    end;
    ()
  )

Example 4.22: tc -XbBA me.tig

This is harder when there are several occurrences of the same name. Note that primitive types are accepted, but have no pre-declaration, contrary to primitive functions.

let
  var me := 0
  function id(me : int) : int = me
in
  me
end

File 4.19: meme.tig

$ tc -XbBA meme.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x5566cd725b00 */() =
  (
    let
      var me /* 0x5566cd7285b0 */ := 0
      function id /* 0x5566cd7272d0 */(me /* 0x5566cd7261e0 */ : int /* 0 */) : int /* 0 */ =
        me /* 0x5566cd7261e0 */
    in
      me /* 0x5566cd7285b0 */
    end;
    ()
  )

Example 4.23: tc -XbBA meme.tig

TC-3 is in charge of incorrect uses of the names, such as undefined names,

me

File 4.20: nome.tig

$ tc -bBA nome.tig
error→nome.tig:1.1-2: undeclared variable: me
⇒4

Example 4.24: tc -bBA nome.tig

or redefined names.

let
  type me = {}
  type me = {}
  function twice(a: int, a: int) : int = a + a
in
  me {} = me {}
end

File 4.21: tome.tig

$ tc -bBA tome.tig
error→tome.tig:3.3-14: redefinition: me
error→tome.tig:2.3-14: first definition
error→tome.tig:4.25-31: redefinition: a
error→tome.tig:4.18-23: first definition
⇒4

Example 4.25: tc -bBA tome.tig


In addition to binding names, --bindings-compute is also in charge of binding the break to their corresponding loop construct.

let var x := 0 in
  while 1 do
  (
    for i := 0 to 10 do
    (
      x := x + i;
      if x >= 42 then
        break
    );
    if x >= 51 then
      break
  )
end

File 4.22: breaks-in-embedded-loops.tig

$ tc -XbBA breaks-in-embedded-loops.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x55a197e92b00 */() =
  (
    let
      var x /* 0x55a197e955e0 */ := 0
    in
      (while /* 0x55a197e960a0 */ 1 do
        (
          (for /* 0x55a197e94ae0 */ i /* 0x55a197e94280 */ := 0 to 10 do
            (
              (x /* 0x55a197e955e0 */ := (x /* 0x55a197e955e0 */ + i /* 0x55a197e94280 */));
              (if (x /* 0x55a197e955e0 */ >= 42)
                then break /* 0x55a197e94ae0 */
                else ())
            ));
          (if (x /* 0x55a197e955e0 */ >= 51)
            then break /* 0x55a197e960a0 */
            else ())
        ))
    end;
    ()
  )

Example 4.26: tc -XbBA breaks-in-embedded-loops.tig

break

File 4.23: break.tig

$ tc -b break.tig
error→break.tig:1.1-5: `break' outside any loop
⇒4

Example 4.27: tc -b break.tig

Embedded loops show that there is scoping for breaks. Beware that there are places, apparently inside loops, where breaks make no sense too.


Although it is a matter of definitions and uses of names, record members are not bound here, because it is easier to implement during type checking. Likewise, duplicate fields are to be reported during type checking.

let
  type     box = { value : int }
  type     dup = { value : int, value : string }
  var      box := box { value = 51 }
in
  box.head
end

File 4.24: box.tig

$ tc -XbBA box.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x55c8f9b45ed0 */() =
  (
    let
      type box /* 0x55c8f9b44db0 */ = { value : int /* 0 */ }
      type dup /* 0x55c8f9b440a0 */ = {
        value : int /* 0 */,
        value : string /* 0 */
      }
      var box /* 0x55c8f9b44750 */ := box /* 0x55c8f9b44db0 */ { value = 51 }
    in
      box /* 0x55c8f9b44750 */.head
    end;
    ()
  )

Example 4.28: tc -XbBA box.tig

$ tc -T box.tig
error→box.tig:3.33-46: identifier multiply defined: value
error→box.tig:6.3-10: invalid field: head
⇒5

Example 4.29: tc -T box.tig

But apart from these field-specific checks delayed at TC-4, TC-3 should report other name-related errors. In particular, a field with an invalid type name is a binding error (related to the field’s type, not the field itself), to be reported at TC-3.

let
  type rec = { a : unknown }
in
  rec { a = 42 }
end

File 4.25: unknown-field-type.tig

$ tc -XbBA unknown-field-type.tig
error→unknown-field-type.tig:2.20-26: undeclared type: unknown
⇒4

Example 4.30: tc -XbBA unknown-field-type.tig


Likewise, class members (both attributes and methods) are not to be bound at TC-3, but at the type-checking stage (see TC-4). Therefore, no bindings are to be displayed in regards to object at TC-3.

let
  type C = class {}
  var c := new C
in
  c.missing_method();
  c.missing_attribute
end

File 4.26: bad-member-bindings.tig

$ tc -X --object-bindings-compute -BA bad-member-bindings.tig
/* == Abstract Syntax Tree. == */

function _main /* 0x55914f1e3b00 */() =
  (
    let
      type C /* 0x55914f1e4610 */ = 
      class extends Object /* 0 */
      {
      }
      var c /* 0x55914f1e3bd0 */ := new C /* 0x55914f1e4610 */
    in
      (
        c /* 0x55914f1e3bd0 */.missing_method();
        c /* 0x55914f1e3bd0 */.missing_attribute
      )
    end;
    ()
  )

Example 4.31: tc -X --object-bindings-compute -BA bad-member-bindings.tig

$ tc --object-types-compute bad-member-bindings.tig
error→bad-member-bindings.tig:5.3-20: unknown method: missing_method
error→bad-member-bindings.tig:6.3-21: unknown attribute: missing_attribute
⇒5

Example 4.32: tc --object-types-compute bad-member-bindings.tig

Concerning the super class type, the compiler should just check that this type exists in the environment at TC-3. Other checks are left to TC-4 (see TC-4 Samples).

let
  /* Super class doesn't exist.  */
  class Z extends Ghost {}
in
end

File 4.27: missing-super-class.tig

$ tc -X --object-bindings-compute -BA missing-super-class.tig
error→missing-super-class.tig:3.19-23: undeclared type: Ghost
⇒4

Example 4.33: tc -X --object-bindings-compute -BA missing-super-class.tig


Next: , Previous: , Up: TC-3   [Contents][Index]