Kevo(ID:1691/kev001)

Stack and prototype-based object-oriented language 


name for northern Finland natural area (basically Finnish Lapland)

A. Taivalsaari Helsinki Finland and U Victoria, June 1992.

Prototype-based object-oriented system built around a threaded code interpreter. Semantically resembles Self and Omega. Syntacically resembles Forth.

"Experimental prototype-based object-oriented system. Although the Kevo system has been built to experiment with ideas which are somewhat irrelevant from the viewpoint of Forth, the system does bear some resemblance to Forth; in particular, the system executes indirect threaded code, and a great deal of the primitives are similar to those of Forth's."


Structures:
Related languages
FORTH => Kevo   Extension of
Omega => Kevo   Influence
Self => Kevo   Influence

References:
  • Taivalsaari, A "Prototype-based object-oriented system built around a threaded code interpreter" TR DCS-197-19, U Victoria, June 1992 view details
  • Taivalsaari, Antero "A classified list of primitives implemented in the Kevo kernel" view details Abstract: This document contains a classified list of primitives implemented in the Kevo kernel, as of Kevo version 0.9b6. Certain unimportant operations have deliberately been left out of the document, but otherwise the list is comprehensive.

    Some operations have been marked with an asterisk (*). This indicates that the operation is intended primarily for internal use by the system, and isn't normally supposed to be executed directly by the user.

    Some operations have been marked with a carat (^). This indicates that the operation is seemingly similar to that in ANSI Forth, but the actual behavior is different.

    Note that Kevo is a case-sensitive system, and all words must be typed using correct capitalization. In many cases, the same word obeys a different calling convention when written using different key case. For instance, the word 'SEE' takes its parameter from the input stream (e.g., SEE hello), whereas 'see' receives its parameter in the stack (e.g., " hello" see). By convention, a word written in all caps is immediate, i.e., executed at compile time, whereas lower case words are typically intended for runtime execution.

    For a more detailed description of the primitives, including their stack effects, refer to the source code and the standard image file 'kevo.img'.


      /* Data loading primitives */
      (=sharedVar)          (*)     load address of a shared variable
      (=taskVar)             (*)     load address of a task-specific var
      (=sharedConst)           (*)     load shared constant
      (=taskConst)            (*)     load task-specific constant
      (=sharedVector)          (*)     shared vectored execution
      (=taskVector)          (*)     task-specific vectored execution
      (=context)          (*)     denotes an object-oriented object
      (=REF)               (*)     load a shared to-variable
      (=VAR)               (*)     load an object-specific to-variable
      (lit)               (*)     load a literal
      ("lit)               (*)     load a string literal


      /* Execution primitives */
      noop                    no operation
      execute                    execute an operation
      exit                    exit a routine
      freeExit               (*)     exit a routine, deallocating memory
      killExit               (*)     exit a routine, killing the task
      debugExit               (*)     exit a routine in debug mode
      reboot               (*)     reboot the system using given operation


      /* Data stack primitives */
      top                         no operation
      dup                         duplicate topmost item in data stack
      2dup                    duplicate two topmost items
      ?dup                    duplicate if non-zero
      drop                    drop topmost
      2drop                    drop two topmost items
      swap                    swap two topmost
      2swap                    swap two cells at a time
      over                    copy second topmost to top
      2over                    'over' two cells at a time
      rot                         rotate third topmost onto top
      -rot                    rotate topmost to third topmost
      nip                         = swap drop ;
      tuck                    = swap over ;
      pick               (^)     copy n'th item to the top (1 = top)
      roll               (^)     rotate stack left or right (+/-n items)
      depth                    return current stack depth
      .s                         print stack contents
      sp#                         return current maximum data stack size
      resizeDataStack          (*)     change data stack size
      resetSp                    empty data stack



      /* Return stack primitives */
      >r                    (*)     push to return stack
      r@                    (*)     copy topmost to data stack
      r>                    (*)     pop from return stack
      i                         innermost loop index
      j                         second innermost loop index
      dup>r               (*)     = dup >r ;
      r>drop               (*)     = r> drop ;
      rdepth                    return current return stack depth
      .rs                         print return stack contents
      rp#                     return current max return stack size
      resizeReturnStack     (*)     change return stack size


      /* Temporary variable primitives (frames) */
                     (*)     allocate a local variable (runtime)
      temp:               (*)     access a local variable (runtime)
      ({)                    (*)     open a local variable frame (runtime)
      {                         open a local variable frame (compile)
      (})                    (*)     close a local variable frame (runtime)
      }                         close a local variable frame (compile)
      (=template)          (*)     denote a temporary variable
      forgetTemp          (*)     delete a compile-time temp variable
      forgetTemps          (*)     delete all temp variables in a frame
      TEMP                    define a local to-variable (compile)


      /* Context stack primitives */
      self                    return receiver of current message
      &                         return receiver of previous message
      >self               (*)     push to context stack
      self>               (*)     pop context stack
      self>drop               (*)     = self> drop ;
      >area               (*)     return beginning of object's data area
      area0               (*)     return beginning of self's data area
      area#               (*)     size of self object's data area
      >send               (*)     send a message (internal)
      >resend               (*)     resend a message (internal)
      send               (*)     send a message to an object
      resend                    resend a message ("super")
      cdepth                    return current context stack depth
      .cs                         print context stack contents
      cp#                         return current max context stack size
      resizeContextStack     (*)     change context stack size
      resetCp               (*)     reset the context stack pointer
      resetContext          (*)     reinitialize context stack pointer

      /* Memory access primitives */
      @                         fetch from a memory address (32 bit)
      !                         store to a memory address
      +!                         increment to a memory address
      w@                         fetch from a memory address (16 bit)
      w!                         store to a memory address
      w+!                         increment to a memory address
      b@                         fetch from a memory address (8 bit)
      b!                         store to a memory address
      b+!                         increment to a memory address
      on                         store -1 to an address (32 bit)
      off                         store zero to an address
      woff                     store zero to an address (16 bit)
      boff                    store zero to an address (8 bit)
      ++                         increment an address by one
      cell++                     increment an address by four
      --                         decrement an address by one
      cell--                    decrement an address by four
      toggle                    set bits in a memory location (32 bit)
      untoggle                    unset bits in a memory location
      btoggle                    set bits in a memory location (8 bit)
      buntoggle                    unset bits in a memory location
      align                    align given address to next even cell
      move               (^)     move memory (src lenInBytes dest move)
      fill                    fill an area of memory with given byte
      (->)               (*)     to-variable assignment (internal op)
      ->                         to-variable assignment
      room                    return amount of free memory
      lowMem                    give lowest addressable memory address
      highMem                    give highest addressable memory address


      /* Integer arithmetic primitives */
      +                         add
      -                         subtract
      *                         multiply
      /                         divide
      mod                         return modulus
      /mod                    return both quotient and remainder
      u/                         unsigned division
      umod                    unsigned modulus
      u/mod                    unsigned /mod
      1+                         1 + ;
      2+                         2 + ;
      cell+                    4 + ;
      1-                         1 - ;
      2-                         2 - ;
      cell-                    4 - ;
      2*                         multiply by two
      2/                         divide by two
      cell*                    multiply by four
      cell/                    divide by four
      abs                         absolute value
      negate                    negate (two's complement)
      +/-                         synonym of 'negate'


      /* Comparison primitives */
      0=                         test if zero
      0<>                         test if nonzero
      0<                         test if less than zero
      0>                         test if greater than zero

      =                         test if equal
      <>                         test if not equal
      <                         test if less
      <=                         test if less or equal
      >                         test if greater
      >=                         test if greater or equal
      u<                         unsigned test if less
      u>                         unsigned test if greater
      min                         return smaller of two topmost
      max                         return larger of two topmost
      between                    check if a value is within given range


      /* Logical primitives */
      and                         logical and
      or                         logical or
      xor                         logical exclusive or
      not                         logical not (one's complement)
      <<                         left shift
      >>                         right shift


      /* Literal primitives */
      zero                    load zero to stack
      one                         load one to stack
      cell                    load four to stack
      false                    load false (0)
      true                    load true (-1)
      "bs"                    load ASCII value of backspace
      "tab"                    load ASCII value of tab
      "lf"                    load ASCII value of linefeed
      "cr"                    load ASCII value of carriage return
      "bl"                    load ASCII value of space
      "del"                    load ASCII value of delete
      ASCII                    compile a character literal (ASCII x)


      /* Control structure primitives */
      (branch)               (*)     unconditional branch
      (if)               (*)     branch if zero
      (do)               (*^)     begin loop (conditionally)
      (-do)               (*)     begin loop (executed at least once)
      (loop)               (*^)     end loop (increment by one)
      (+loop)               (*^)     end loop (increment by n)
      (msecsDo)               (*)     begin loop (execute for n milliseconds)
      (msecsLoop)          (*)     end loop (execute for n milliseconds)
      leave                    exit loop immediately
      mark>               (*)     create a forward reference
      resolve>               (*)     resolve a forward reference
      mark<               (*)     mark a backward reference
      resolve<               (*)     resolve a backward reference
      ensureStruct          (*)     ensure validity of control structures
      "if"               (*)     literal for syntax checking (IF-THEN)
      "begin"               (*)     literal for syntax checking (BEGIN)
      "while"               (*)     literal for syntax checking (WHILE)
      "do"               (*)     literal for syntax checking (DO-LOOP)
      "of"               (*)     literal for syntax checking (CASE)
      ":"                    (*)     literal for syntax checking (: ;)
      "{}"               (*)     literal for syntax checking (frames)

      /* Internal structure primitives */
                (*)     allocate a name structure
                (*)     allocate an object structure
                (*)     allocate a context structure
                (*)     allocate a store structure
                (*)     allocate an ASCIZ string
                (*)     build a background task (no own window)
                (*)     build a graphics task (own window)
                (*)     build a grachics&text task (TextEdit)
                (*)     delete a task if not running
                (*)     delete a task even if running
                (*)     remove a name from its context
                (*)     rename a name structure
                (*)     execute a store structure
                     (*)     build an "empty" object
                (*)     shallow copy an object
                     (*)     ensure individuality of an object
                     (*)     resize an object
                     (*)     expand an object
                (*)     expand all the members in a family
                (*)     optimize memory consumption of object
                     (*)     dispose of an object
                     (*)     free an allocated structure
                (*)     free the store part of an object
                (*)     recompile the rest of a context
                     (*)     rebind the rest of early bindings
                (*)     reorganize the family hierarchy
                     (*)     internal operation (subject to change)
      checkSystemValidity          perform system integrity checks


      /* Internal structure maneuvering primitives */
      name>object          (*)     go from the name part to the object
      name'object          (*)     return the object field of the name
      name'name               (*)     return the name field of the name
      name'flags          (*)     return the flag field of the name
      name'prev               (*)     return the previous name in a link
      name'succ               (*)     return the successor name in a link
      name'context          (*)     return the context field of the name
      object>name          (*)     find a name given an object
      object>typename          (*)     find a type name given an object
      object>store          (*)     go from the object to its store part
      object'store          (*)     return the store field of the object
      object'size          (*)     return the size field of the object
      object>context          (*)     go from object to its context (if any)
      context'thread          (*)     return the n'th thread of the context
      context'first          (*)     return the first name in the context
      context'latest          (*)     return the latest name in the context
      context'family          (*)     return the clone family of the context
      context'parents          (*)     return the parents of the context
      context'children     (*)     return the children of the context
      #threads               (*)     return number of threads in hash table
      default#               (*)     default size of objects (in cells)
      "immediate"          (*)     return the immediate bit as a literal
      "hidden"               (*)     return the hidden bit as a literal
      "smudge"               (*)     return the smudge bit as a literal
      "thisOnly"          (*)     return "this only" mode as a literal
      "wholeFamily"          (*)     return "whole family" mode as a literal
      "derivatives"          (*)     return "derivatives" mode as a literal

      /* Dictionary (context) search primitives */
      searchThis          (*)     search for a name in this context only
      search                    search for a name using default path
      find                    search for a name (" name" find)
      FIND                    search for a name (FIND name)
      tick                    search for an object ("name" tick)
      '                         search for an object (' name)
      immediate?               check if a name is marked immediate
      DEFINED                    check if a name exists (DEFINED name)
      respondsTo               check if object responds to certain msg


      /* String manipulation primitives */
      /* Note: Kevo uses zero-terminated (ASCIZ) strings */
      count               (^)     count the length of an ASCIZ string
      match                    compare two ASCIZ strings
      scan                    scan for a character
      scanWhite                    scan for a whitespace character
      skip                    skip requested characters
      skipWhite                    skip all whitespaces
      enclose                    extract a word separated by whitespace
      number                    convert a string to a number
      "                         create a string literal (" string")
      ."                         print a string literal (." string")
      ^                         synonym of '"'
      .^                         synonym of '."'


      /* Multitasker primitives */
      up                         pointer to current task
      multitasking               true if multitasking is on
      running                    check if a certain task is running
      #tasks                    return the total number of tasks
      #running                    return the number of running tasks
      basePriority               base priority of tasks
      taskingMode               multitasking mode (0=preemptive)
      preemptive               set preemptive multitasking mode
      cooperative               set cooperative multitasking mode
      yield                    force a task switch
      <|                         begin a critical region
      |>                         end a critical region
      (wait)               (*)     semaphore p operation (internal)
      WAIT                    semaphore p operation (REF x WAIT x)
      (signal)               (*)     semaphore v operation (internal)
      SIGNAL                    semaphore v operation (SIGNAL x)
      activate                    activate a certain task
      suspend                    suspend a certain task
      stop                       stop the current task
      does                    set the behavior of a task
      raisePriority               multiply task priority by two
      lowerPriority               divide task priority by two
      resetPriorities               reset priorities of all tasks to basepr
      >taskData               (*)     push a value to data stack of a task
      >taskReturn          (*)     push a value to return stack of a task
      >taskContext          (*)     push a value to context stack of a task


      /* Decompilation primitives */
      isPrintable               check if a character is printable
      dump                (^)     dump memory in ascii and hex format
      see                         decompile a definition (" name" see)
      SEE                         decompile a definition (SEE name)
      mirror                    decompile all definitions in a context
      allnames                     print all names in given context
      allwords                    print all names in current context
      succWords           (*)     print all successive names
      words                    print public names in given context
      names                    print public names in current context
      .threads                    print each name thread separately


      /* Debugging and tracing primitives */
      trace                    set trace mode on
      fullTrace                    set full trace mode on
      endTrace                    disable trace mode
      debug                    set a breakpoint
      unbug                    remove a breakpoint
      resume                    resume execution after breakpoint
      r                         synonym for 'resume'


      /* Input/output primitives */
      emit                    output a single character
      type               (^)     output an ASCIZ string
      ltype                    output an ASCIZ string left-justified
      rtype                    output an ASCIZ string right-justified
      page                    blank the screen (form feed)
      .                         output a number
      u.                         output a number unsigned
      h.                         output a number in hexadecimal
      bell                    sound the bell
      cr                         output a carriage return
      tab                         output a tab
      space                    output a space
      spaces                    output n spaces
      key?                    check if any key is pressed
      key                         wait for a keypress
      expect                    input a string
      query                    input a string to text buffer


      /* File primitives */
      pushInfile          (*)     open a file and push it to infile stack
      popInfile               (*)     pop and close the input file
      resetInfiles          (*)     reset the input file stack
      pushOutfile          (*)     open a file and push it to outfile stak
      popOutfile          (*)     pop and close the output file
      resetOutfiles          (*)     reset the output file stack
      resetFiles          (*)     close all input and output files
      errorTo                    redirect output to error device
      consoleTo                    redirect output to console device
      from                    load a file by redirecting input
      endFrom                    end file loading by popping infile
      to                         redirect output to a file
      >>to                    append output to a file
      endTo                    pop output file stack
      stdInput?               (*)     is input currently from keyboard?
      raiseEof               (*)     force end of file
      fileShell               (*)     shell for loading files
      "write"               (*)     return file "write" mode as a literal
      "append"               (*)     return file "append" mode as a literal


      /* Block file (virtual memory) primitives */
      open-blockfile               open a block file (" file" open-bl...)
      close-blockfile               close a block file
      block                    load a block into memory
      update                    mark the current block to be updated
      discard                    discard changes in current block
      save-buffers               save all changed buffers
      empty-buffers               empty and release all buffers
      flush                    save and empty all buffers
      b/buf                    return buffer size
      more                    add a new block to block file
      capacity                    return size of block file (in blocks)


      /* Host system specific primitives */
      eventDelay               tells how often event loop is called
      eventSlice               tells how much time is given to Mac
      clock                    return the value of system clock
      ticks>msecs               convert system clock ticks to millisecs
      msecs>ticks               convert millisecs to system clock ticks
      msecs                    pause for n milliseconds
      system                    execute host system commands
      $                          execute host system commands ($ cmd)
      bye                         exit Kevo and return to host system


      /* Task-specific variables and constants */
      /* Each task has copy of this structure (represented as object) */
      nextInRobin          (*)     next task in the round robin chain
      nextTask               (*)     next defined task in the system
      rpStore               (*)     temporary return stack pointer storage
      fp                    (*)     current frame pointer
      priority                    task priority
      returnStack          (*)     return stack
      dataStack               (*)     data stack
      contextStack          (*)     context stack
      trampoline          (*)     interactive execution area
      textBuffer          (*)     text buffer
      textHead               (*)     pointer to next character to be read
      textTail               (*)     pointer to the end of the text buffer
      eof                    (*)     end of file flag
      infiles               (*)     input file stack
      outfiles               (*)     output file stack
      infile'               (*)     input file stack pointer
      outfile'               (*)     output file stack pointer
      infile               (*)     current input file
      outfile               (*)     current output file
      errfile               (*)     current error file
      window                    current window of the task
      path               (*)     search path (obsolete)
      assigning               (*)     assignment counter
      error                    error vector
      user'               (*)     number of task-specific variables
      compilation          (*)     current definition under compilation
      target               (*)     latest compiled definition
      latest               (*)     latest defined name
      frameSize               (*)     compile-time temporary variable count
      whoToModify          (*)     current module operation mode
      controls               (*)     number of open control structures
      warnings                    are compilation warnings on?
      tram'               (*)     ptr to latest compiled thread (exec)
      comp'               (*)     ptr to latest compiled thread (comp)
      text'               (*)     text buffer pointer
      input               (*)     latest encoded name (for error msgs)

      /* Pseudovariables */
      user0               (*)     beginning of task data area
      user#               (*)     size of task data area
      text0               (*)     beginning of text buffer
      text#               (*)     size of text buffer
      infile0               (*)     beginning of input file stack
      infile#               (*)     size of input file stack
      outfile0               (*)     beginning of output file stack
      outfile#               (*)     size of output file stack
      tram0               (*)     beginning of execution trampoline
      tram#               (*)     size of execution trampoline
      comp0               (*)     beginning of current definition
      comp#               (*)     size of current definition area
      here0               (*)     either tram0 or comp0
      here'               (*)     either tram' or comp'
      here#               (*)     either tram# or comp#
      here                    return current memory location


      /* Execution state manipulation */
      >compile               (*)     set compilation mode
      >execute               (*)     set execution mode
      executing                    return true if executing
      compiling                    return true if compiling
      mustCompile          (*)     ensure we are currently compiling
      mustExecute          (*)     ensure we are currently executing


      /* Compilation primitives */
      allot               (^)     allocate space in either tram or comp
      ,                    (^)     compile a cell to either tram or comp
      compile,                    compile a call to given routine
      override,               (*)     override previous compilation
      literal,               (*)     compile a literal
      "literal,               (*)     compile a string literal
      (compile)               (*)     compile a call to next operation
      tramAllot               (*)     allocate space in trampoline
      tram,               (*)     compile a cell to trampoline
      recurse                    compile a recursive call to itself
      myself                    compile a recursive jump to itself
      COMPILE                    compile a call (COMPILE xxx)
      NOW                         execute right away (NOW xxx)
      LATER                    postpone execution (LATER xxx)


      /* Task data area primitives */
      userAllot               (*)     allocate cells in task data area     
      user,               (*)     compile a cell into task data area
      my                    (*)     access this task's data area
      MY                    (*)     access this task's data area (MY input)
      his                    (*)     access another task's data area
      HIS                    (*)     access another task's data area


      /* Interactive execution primitives */
      cycle               (*)     recycle trampoline memory
      go                    (*)     execute trampoline code
      (|)                    (*)     run the compiled command line
      |                         treat command line as 2 separate lines
      (BG|)               (*)     background execution internal
      (runBG)               (*)     background execution internal
      BG                         run a command line on background
                             (cmd1 cmd2 ... cmdN BG)

      /* Command input stream primitives */
      textAvailable               check if there is text in input buffer
      eraseText               (*)     erase text input buffer
      prepareText          (*)     prepare input buffer for interpretation
      (word)               (*)     parse text delimited by a character
      WORD                    parse text delimited by a character
      (parse)               (*)     parse text delimited by whitespace
      PARSE               (^)     parse text delimited by whitespace
      (                         begin comment ( this is a comment)
      \                         treat rest of the line as comment


      /* Message expression parser */
      noDotsAtAll          (*)     ensure a string does not contain dots
      dotInBeginning          (*)     ensure a string does not begin with '.'
      dotInEnd               (*)     ensure a string does not end with '.'
      dotExpression          (*)     check if a string is a dot expression
      message,               (*)     compile a message send
      skipDot               (*)     skip a dot in a string
      innerMessages          (*)     process inner messages in a dot expr
      lastMessage          (*)     process last message in a dot expr
      encodeMessages          (*)     encode and compile a dot expression
      assignment?          (*)     compile assignment if needed
      ooEncode               (*)     encode and compile a dot expression
      encode               (*)     vectored encoding
      (encode)               (*)     process a word in command line


      /* Command shell */
      interpret               (*)     interpret a line in the text buffer
      "interpret               interpret the given string
      checkStacks               check the validity of all stacks
      .ok                    (*)     print prompt string
      prompt               (*)     prompt if necessary
      shell                    the command shell


      /* Error handling */
      abort                    abort execution and return to shell
      (error)               (*)     low-level error handler
      oopError               (*)     higher-level error handler
      brError               (*)     internal error handler for browsers


      /* High-level structure definition */
      warn               (*)     warn about overridden definitions
      rewarn               (*)     warn about redefined definitions
      (create)               (*)     low-level object creation
      create               (^)     create a definition (" xxx" create)
      CREATE               (^)     create a definition (CREATE xxx)
      does,               (*)     store to execution field
      with,               (*)     store to parameter field
      (replace)               (*)     low-level general redefinition
      replace               (*)     redefine the behavior of definition
      (recreate)          (*)     low-level redefinition for clone fams
      recreate               (*)     redefine definition in a clone family
      (:)                    (*)     low-level colon definition
      bredef               (*)     internal op needed by the browser
      (REF)               (*)     define a shared variable
      REF                         define a shared variable
      (VAR)               (*)     define a local variable
      VAR                         define a local variable
      CONST                    define a constant
      SHAREDVAR                    synonym of 'REF'
      METHOD                    synonym of ':'
      :                         begin a colon definition (method)
      ;                         end a colon definition
      immediate                    make the latest definition immediate
      hidden                    make the latest definition hidden
      smudge               (*)     make the latest definition invisible
      unsmudge               (*)     make the latest definition visible
      (ADDS)               (*)     start adding properties to an object
      ADDS                    start adding properties to an object
      (ADDS*)               (*)     start adding ... to all in clone family
      ADDS*                    start adding ... to all in clone family
      ADDS**                    start adding ... to a larger group
      (ENDADDS)               (*)     end property addition
      ENDADDS;                    end property addition
      REDEFINE                    redefine a method in an object
      REDEFINE*                    redefine a method in a clone family
      REDEFINE**               redefine a method in a larger group
      rename                    rename a property in single object
      RENAME                    rename a property in single object
      rename*                    rename a property in clone family
      RENAME*                    rename a property in clone family
      RENAME**                    rename in a larger group
      remove                    remove a property from single object
      REMOVE                    remove a property from single object
      remove*                    remove from all in a clone family
      REMOVE*                    remove from all in a clone family
      REMOVE**                    remove from a larger group
      hide                    make a property hidden (i.e., private)
      HIDE                    make a property hidden (i.e., private)
      hide*                    make hidden in a clone family
      HIDE*                    make hidden in a clone family
      HIDE**                    make hidden in a larger group
      show                    make a property visible (i.e., public)
      SHOW                    make a property visible (i.e., public)
      show*                    make visible in a clone family
      SHOW*                    make visible in a clone family
      SHOW**                    make visible in a larger group


      /* Context management */
      SystemRoot               return address of system root context
      Root                    return address of user root context
      MKDIR                    build an empty object (MKDIR Test)
      hasContext               check if the given object has a context
      mustBeObject               ensure that given value is an object
      cd                         set the "current working directory"
      CD                         set the "current working directory"
      pwd                         display the "current working directory"
      home                    go back to 'Root' context


      /* Control structures */
      /* Unlike other primitives, these are described with examples */
      IF                          IF xxx ELSE yyy THEN
      ELSE
      THEN                    
      BEGIN                    BEGIN xxx AGAIN
      AGAIN
      UNTIL                    BEGIN xxx UNTIL
      WHILE
      REPEAT                    BEGIN xxx WHILE yyy REPEAT

      DO                    (^)     10 1 DO i . LOOP (goes from 1 to 10)
      TIMES                    1000 TIMES LOOP (TIMES = 1 DO)
      MSECS                    200 MSECS LOOP (loop for 2 seconds)
      LOOP
      +LOOP               (^)     100 1 DO i . 10 +LOOP (increment by 10)
      CASE               (^)     n CASE
      OF                    (^)          10 < OF ." Less than 10"   ENDOF
      ENDOF               (^)          20 > OF ." More than 20"   ENDOF
      ELSEOF               (^)           ELSEOF ." Something else" ENDOF
      ENDCASE               (^)     ENDCASE


      /* Random number generator */
      seed               (*)     random number seed
      randomize                  randomize the random number seed
      random                    return a random integer
      rnd                         return a random number in certain range


      /* GUI window primitives */
                (*)     build a window
            (*)     build a window with a TextEdit
      showWindow               display a window
      hideWindow               hide a window
      selectWindow               select a window (make it topmost)
      frontWindow               return the frontmost window
      nextWindow               return next topmost window
      getWindowTitle               get window title
      setWindowTitle               set window title
      getWindowSize               get window size               
      setWindowSize               set window size
      getWindowLoc               get window location
      setWindowLoc               set window location
      getWindowKind               get window kind
      TEDeactivate               deactivate a Mac TextEdit
      TEActivate               activate a Mac TextEdit
      

      /* GUI mouse & graphics primitives */
      getMouse                    get current mouse coordinates
      button                    true if mouse button pressed
      setPort                    set graphics port
      getPort                    get graphics port
      hidePen                    hide pen
      showPen                    show pen
      getPen                    get pen location
      setPenSize               set pen size
      setPenMode               set pen mode
      penNormalize               reinitialize pen
      moveTo                    move graphics cursor to (x,y)
      moveDelta                    increment graphics cursor with (dx, dy)
      lineTo                    draw a line to (x,y)
      lineDelta                    draw a line to (dx, dy)
      setTextFont               set text font
      setTextFace               set text face
      setTextMode               set text mode
      setTextSize               set text size
      drawChar                    draw a character
      drawString               draw a text string
      wipeScreen               wipe the graphics off the screen
      browse                    open a browser for an object
      unbrowse                    close a browser for an object (if any)
      cfBrowse               (*)     open a browser for a clone family

      /* System startup */
      hello                    greet the user
      demo                    load the default demo programs
      demoInfo                    display info about loading demos
      SystemInit               initialize the system
      boot                    reinitialize the system


      /* Error messages */
      msg$dEmpty          (*)     data stack empty
      msg$dFull               (*)     data stack full
      msg$rEmpty          (*)     return stack empty
      msg$rFull               (*)     return stack full
      msg$cEmpty          (*)     context stack empty
      msg$cFull               (*)     context stack full
      msg$control          (*)     illegal control structure
      msg$what               (*)     name not found
      msg$"what               (*)     name 'x' not found
      msg$execOnly          (*)     for execution only
      msg$compOnly          (*)     for compilation only
      msg$notCtxt          (*)     not a context object
      msg$noDot               (*)     message syntax error
      msg$notImpl          (*)     not implemented
      msg$notAvail          (*)     not available
      notImplemented               raise 'msg$notImpl'
      notAvailable               raise 'msg$notAvail'
      inRange                    ensure that a number is in range


      /* The following operations are redundant and will */
      /* probably be removed from later versions of Kevo */

      (=>)               (*)     alternative to-var assignment (unused)
      =>                         alternative to-var assignment (unused)
      (tick&)               (*)     access the parameter field (obsolete)
      '&                         access the parameter field (obsolete)
      forget                    forget a certain name (" name" forget)
      FORGET                    forget a certain name (FORGET name)
      forgetRest               forget rest of the names
      empty                    forget all after 'boot' (obsolete)
      context                    define a context object
      CONTEXT                    define a context object
      bgtask                    build a background task (" xxx" bgtask)
      BGTASK                    build a background task (BGTASK xxx)
      grtask                    build a graphics task (" xxx" grtask)
      GRTASK                    build a graphics task (GRTASK xxx)
      task                    build a full task (" xxx" task)
      TASK                    build a full task (TASK xxx)
      sharedVar                    build a shared variable
      taskVar                    build a task-specific variable
      sharedConst               build a shared constant
      taskConst                    build a task-specific constant
      sharedVector               build a shared execution vector
      taskVector               build a task-specific exec vector
      VARIABLE                    define a Forth-style variable
      CONSTANT                    define a Forth-style constant
      DEFER                    define a Forth-style exec vector


  • Taivalsaari, Antero. "Why should object-oriented Forths be based on prototypes rather than classes? The object model of Kevo." In 1992 FORML Conference Proceedings, by the Forth Interest Group. Oakland, CA: Forth Interest Group, 1992, 180-189. view details
  • Taivalsaari, A., Concatenation-based object-oriented programming in Kevo. Actes de la 2eme Conference sur la Representations Par Objets RPO'93 (La Grande Motte, France, June 17-18, 1993), Published by EC2, France, June 1993, pp. 117-130 view details
  • Taivalsaari, Antero "A critical view of inheritance and reusability in object-oriented programming" Ph.D. thesis, University of Jyva"skyla", Finland, November 1993 view details
  • Taivalsaari, Antero "Kevo User's Guide" Universities of Victoria and Tampere view details Extract: About Kevo
    About Kevo

    Kevo is a prototype-based object-oriented system build around a very simple object model. Unlike most object-oriented systems, Kevo does not have classes. And unlike the few other prototype-based object-oriented systems (such as Self), Kevo does not feature delegation. Instead of classes and delegation, Kevo is based on concatenation: unrestricted composition of object interfaces. In concatenation, objects are derived from each other simply by cloning (copying) and subsequently modifying them so as to differentiate them from each other. The Kevo system automatically maintains information about clone families (groups of similar objects) and their derivation relationships.

    The overall organization of the Kevo system differs considerably from most other object-oriented systems. Instead of building the system around inheritance hierarchies, in Kevo the basic skeleton for the system is the part-whole hierarchy. This hierarchy organizes the system into an intuitive Unix-like hierarchical structure in which the individual "directories" are objects rather than files. The user can freely move about in this hierarchy, and change the "current working directory" in a Unix-like manner. The commands given from the command shell will be implicitly interpreted in the "current working directory" so that the user can manipulate objects easily without having to use long message paths to reach a certain object.

    In Kevo, there are several basic ways to create new kinds of objects. Besides that it is possible to define objects using text files (see the demo programs and the papers to get the idea), all the object creation facilities have been integrated into Kevo's user interface. In fact, some of the most interesting functions (such as cut-copy-paste editing of objects) of the Kevo system necessitate the presence of the user interface and cannot necessarily be done textually. Even in the user interface, there are two basic ways to "inherit" existing objects:

    Either you can copy an existing object using the Tools menu, and subsequently make changes to the copy using the Edit facilities (traditional concatenation).

    Alternatively, you can start with an empty object using MKDIR in Edit menu, use copy and paste to "inherit" possibly several existing objects (or just parts of them), and subsequently make changes to the new object (cut-copy-paste concatenation).

    Kevo system also features explicitly selectable early or late binding, regardless of whether the properties to be bound are variables or operations. When using the cut-copy-paste features, Kevo will automatically recompile all the needed properties if they contain early-bound references. For instance, when the user removes a property from an object, the system will recompile all the properties which refer to the removed property (using the name of the removed property), and report all the inconsistencies to the console window. Similarly, when pasting properties in the middle of an object, all the early-bound references will be checked, causing some methods to be possibly recompiled. If only late binding is used, then no recompilations will be made.  

    One curious feature of Kevo is propagation. All the basic object editing functions, such as the addition, removal, renaming, method redefinition, and cut-copy-paste features can be targeted to individual objects or to whole clone families, depending on the propagation settings in the Edit menu. When modifying individual objects, the system will automatically start a new clone family around the modified object. After the modifications have been completed, the system will automatically compare the modified object to other related objects, and possibly move the object upwards or downwards in the clone family hierarchy to some other clone family with matching properties. In other words, Kevo allows objects to automatically migrate in the inheritance hierarchy.

    In the current version of Kevo, the implementation of propagation is still somewhat limited. The idea is to allow the user to easily modify very large groups of objects with only a minimum effort. At the present time the use of the derivatives mode in the Edit menu is however limited to the redefinition of methods only. Note that the effect of large-scale propagation can however be achieved manually quite simply by following the clone family relationships and using cut or paste to do the same modification to each clone family. In general, Kevo is an experimental combination of several previously little investigated ideas. All these ideas still offer many interesting lines of research to pursue:

         ? self-sufficient objects,
         ? use of part-whole hierarchy as the basis for system organization,
         ? automatic management of inheritance hierarchies,
         ? inheritance by copying and subsequent modification (concatenation),
         ? cut-copy-paste editing of objects,
         ? flexible early and late binding, and
         ? runtime modification of the system by change propagation.
  • Taivalsaari, Antero "Kevo: A delegation-free prototype-based object-oriented language" view details Abstract: One of the key features of object-oriented programming languages is incremental modification, i.e., the ability to build and refine programs incrementally, rather than editing existing code. In class-based languages the basic incremental modification mechanism is inheritance, while in prototype-based languages alternative mechanisms exist. Self, for instance, uses delegation as the elementary incremental modification mechanism, allowing objects to flexibly share each others? behavior and state. In the literature delegation is often used as a synonym for prototype-based programming. This is misleading, however, since it is possible to build prototype-based languages which do not support delegation at all, but which nevertheless provide similar support for incremental modification. This was shown by Borning already in 1986, but the ideas were not taken any further. Kevo is an attempt to prove that delegation-free prototype-based languages are indeed feasible and practical. Extract: Introduction to Kevo
    Introduction to Kevo
    Kevo is a prototype-based language designed around self-sufficient and concrete objects, By self-sufficient, it is meant that each Kevo object contains all the properties needed for implementing a certain abstraction, and that these properties are logically independent of the other objects? properties. This is different from Self which relies heavily on sharing, and requires the programmer to divide objects into separate traits and prototype structures. By concrete, it is meant that Kevo allows the programmer to manipulate each object directly, either on a per-object or per-group basis.
    Kevo does not support inheritance in the traditional sense. And unlike many prototype-based object-oriented systems, Kevo does not support delegation.
    Instead of inheritance and delegation, the essence of inheritance - incremental modification - is captured using concatenation, i.e., by duplicating existing objects and by allowing flexible editing and combination of objects. In practice, concatenation is supported by providing two user-redefinable copying operations, new and clone, and a set of module operations that allow different kinds of modifications to be performed on objects. For instance, to create a ColoredPoint object, one would simply copy an existing Point object, and then add the desired new properties to the copy using the module operation ADDS. Late binding of methods and variables ensures that earlier defined (?inherited?) properties can adapt to later modifications in an incremental fashion.
    As a result of the above mentioned arrangements, Kevo objects look quite different from Self objects.
    Extract: Benefits/Issues of Prototypes vs. Classes
    Benefits/Issues of Prototypes vs. Classes
    Prototypes have many benefits especially when exploratory programming is concerned. They are cognitively more lightweight than classes, support direct manipulation more naturally, avoid many modularity problems of class-based systems, and result in simpler and conceptually more elegant language implementations. Considering these benefits, it is appropriate to ask why haven't prototype-based systems received more widespread acceptance thus far.
    Besides the easy explanation - lack of maturity - the best answer to this question seems to be that there has been an over-emphasis on technical issues. The advocates of prototype-based systems have failed to advertise the conceptual benefits of prototypes, and emphasized technical curiosities instead. While features such as unanticipated sharing of data slots, dynamic inheritance, and prioritized parents are often useful, they are questionable and even dangerous in serious, large-scale software development. Compared to other issues, these features have received considerable attention in the literature, diverting the focus away from the real benefits of prototypes, and may have increased resistance against adopting prototype- based techniques more widely.
    In summary, prototypes are beneficial, but a more concept-oriented view of prototypes is still lacking, and this is exactly what we should be aiming at in the future. Delegation-free languages serve as a promising alternative in this respect.
          in Smith, Randall B (moderator) "Prototype-based languages (panel): object lessons from class-free programming" OOPSLA 94 pp102-112 view details
  • Abadi, Martin and Cardelli, Luca "A Theory of Objects" Springer Monographs in Computer Science, 1996 view details

          in Smith, Randall B (moderator) "Prototype-based languages (panel): object lessons from class-free programming" OOPSLA 94 pp102-112 view details
  • Bradford J. Rodriguez & W. F. S. Poehlman "A Survey of Object-Oriented Forths" view details
          in SIGPLAN Notices 31(04) April 1996 view details
  • Noble, James report on Antero Taivalsaari's presentation on Prototyping theory, with reference to Kevo view details Abstract: Antero Taivalsaari from the Nokia Research Centre in Helsinki presented some philosophical and historical observations on classes and prototypes. He traced the philosophical origins of class based languages, stemming from Plato's distinction between classes and instances and Aristotle's interest in hierarchical classification. He argued that prototype based languages were inspired by Wittgenstein's criticism of classification -- that it is difficult to say in advance what properties or hierarchies will be required, and so concepts are best defined by family resemblances between similar objects. This was developed into prototype theory by Eleanor Rosch in the mid seventies, which states that some particular members of families (prototypes) are better representatives of that family than others.
    Antero then presented several consequences of this philosophical background. Because classifications cannot be determined in advance, there can be no optimum class hierarchies, and class library designs need to evolve over time. Class hierarchies evolve from the ``middle out'', in particular, classes high in the hierarchy will be very general and discovered after the more basic classes. Unfortunately, class based languages require that class hierarchies are defined top down, with the most abstract classes being written first. Prototype based languages which use family resemblances rather than class hierarchies (such as Kevo) can avoid these problems.
          in Cointe, P. editor, Proceedings of the Ninth European Conference on Object-Oriented Programming (ECOOP), July 1996. LNCS 1098, Springer-Verlag view details
  • Taivalsaari, Antero "Classes vs. PrototypesSome Philosophical and Historical Observations" Nokia Research Center P.O. Box 45, 00211 Helsinki April 22, 1996 view details Extract: Introduction
    Introduction

    "Objects in the real world have only one thing in common -- they are all different."

    In the recent years an alternative to the traditional class-based object-orientedlanguage model has emerged. In this prototype-based paradigm [Bor86, Lie86, LTP86, Ste87, UnS87, SLU88, DMC92, Bla94] there are no classes. Rather, newkinds of objects are formed more directly by composing concrete, full-fledged objects, which are often referred to as prototypes. When compared to class-basedlanguages, prototype-based languages are conceptually simpler, and have many other characteristics that make them suitable especially to the development of evolving,exploratory and distributed software systems.

    The distinction between class-based and prototype-based systems reflects a long-lasting philosophical dispute concerning the representation of abstractions. Plato viewed forms -- stable, abstract, "ideal" descriptions of things -- as having anexistence more real than instances of those things in the real world. Class-based languages such as Smalltalk, C++ or Simula are Platonic in their explicit use ofclasses to represent similarity among collections of objects. Prototype-based systems such as Self [UnS87], Omega [Bla91, Bla94], Kevo [Tai92, Tai93], GlyphicScript[Gly94] and NewtonScript [SLS94] represent another view of the world, in which one does not rely so much on advance categorization and classification, but rather tries tomake the concepts in the problem domain as tangible and intuitive as possible. A typical argument in favor of prototypes is that people seem to be a lot better at dealingwith specific examples first, then generalizing from them, than they are at absorbing general abstract principles first and later applying them in particular cases. Prototypes give rise to a broad spectrum of interesting technical, conceptual andphilosophical issues. In this paper we take a rather unusual, non-technical approach and investigate object-oriented programming and the prototype-based programmingfield from a purely philosophical viewpoint. Some historical facts and observations pertaining to objects and prototypes are presented, and conclusions based on thoseobservations are derived.


          in Cointe, P. editor, Proceedings of the Ninth European Conference on Object-Oriented Programming (ECOOP), July 1996. LNCS 1098, Springer-Verlag view details
  • Taivalsaari, Antero "On the Notion of Inheritance" ACM Computing Surveys, Vol. 28, No. 3, September 1996 view details Abstract: One of the most intriguing?and at the same time most problematic?notions in object-oriented programming is inheritance. Inheritance is commonly regarded as the feature that distinguishes object-oriented programming from other modern programming paradigms, but researchers rarely agree on its meaning and usage. Yet inheritance is often hailed as a solution to many problems hampering software development, and many of the alleged benefits of object-oriented programming, such as improved conceptual modeling and reusability, are largely credited to it. This article aims at a comprehensive understanding of inheritance, examining its usage, surveying its varieties, and presenting a simple taxonomy of mechanisms that can be seen as underlying different inheritance models.
          in Cointe, P. editor, Proceedings of the Ninth European Conference on Object-Oriented Programming (ECOOP), July 1996. LNCS 1098, Springer-Verlag view details
  • Noble, James; Taivalsaari, Antero; Moore, Ivan (eds) "Prototype-Based Programming: Concepts, Languages, Applications" Springer-Verlag, 1999 view details
          in Cointe, P. editor, Proceedings of the Ninth European Conference on Object-Oriented Programming (ECOOP), July 1996. LNCS 1098, Springer-Verlag view details
    Resources
    • FTP in Finland

      "