[Skip Navigation] [CSUSB] / [CNS] / [Comp Sci Dept] / [R J Botting] / [Samples] / smalltalk.syntax
[Index] [Contents] [Source Text] [About] [Notation] [Copyright] [Comment/Contact] [Search ]
Tue Sep 18 15:27:04 PDT 2007

Contents


    .Title XBNF of Little Smalltalk Version 3.0 Based on samples and Appendix 2 of Timothy Budd's "A Little Smalltalk" QA76.6 B835 1987 Addison-Wesley ISBN 0-201-10698-1

    [ smalltalk.glossary ] [ smalltalk.methods.syntax ] [ glossary.objects ] [ math.syntax ] [ comp.text.ASCII.html ]

    Interactive User Input

    The user supplies a series of commands to the interpreter each terminated by an end_of_line character and containing a special kind of expression:
  1. user_input::=#command CTRL_D.
  2. command::= cascaded_expression EOLN.

    Smalltalk 3 prints the result of each command.

  3. user_output::=prompt #(output_of_command value_of_command EOLN prompt).

    Example commands


    1. 1 + 2
    2. Number viewMethod: #+
    3. 5 factorial
    4. #(1 2 3) size
    5. 'cat' at: 3 put: p; at: 2 put: u

    Summary of Semantics

    The interpreter reads a line of user input and parses it according to the syntax. The syntax determines where to start evaluating the expression - with the simplest subexpression. The syntax also determines, for expression two parts: an object, and a message that it will be sent. The interpretter works by sending a message to an object and the getting a value back. This is also an object which can either be sent more messages, or can become part of a message that is sent to another object (as determined by the syntax) or even both.

    When a message is sent to an object the object's class determines what to do with it. Each class has a dictionary of message templates against which the incoming message is matched. If there is no matching template then the message is sent to the classes superclass (parent), and so on. When a matching message is found, then the arguments in the incoming message are associated with the arguments in the template and a piece of Smalltalk code called the method for that message is interpretted. In this code there are local variables, global (shared) variables, and the arguments from the message - and all of these are assigned to objects. The variable 'self' is object that got the message as well. The method is already compiled into a special machine independent "byte code". This is a series of compiled expressions that are obeyed one step at a time. Each expression is interpretted by the rules in this paragraph.

    Ultimately a value comes out of the expression and this is printed. Meanwhile the methods that have been obeyed may have produced output and may also have changed the environment in which they exist, and themselves in complicated ways.

    .Details /u/faculty/dick/cs320/smalltalk.semantics

    Expressions and Objects

    The Basic Smalltalk expressions are organised in a hierarchy:
    keyword expression'cat', 'dog' at: 2 put: o
    binary expression1 + 5 factorial
    unary expression 5 factorial
    simple expression 5
    The higher ones contain the lower ones inside themselves. The lower ones are evaluated first. A simple expression can be a complex expression in parentheses.

  4. keyword_expression::= binary_expression keyword_message.
  5. keyword_message::=#(keyword binary_expression). So
  6. |-keyword_expression = binary_expression #(keyword binary_expression).

    Notice that each keyword_expression has a keyword_message, and that the message is made up of keywords and actual parameters (expressions). If you delete these actual arguments and concatenate the keywords you get the keyword_selector of the message that Smalltalk uses to identifier that message uniquely.

  7. binary_expression::= unary_expression #binary_message.
  8. binary_message::=binary_selector unary_expression.
  9. |-binary_expression= unary_expression #(binary_selector unary_expression).

  10. unary_expression::= primary #unary_selector.

  11. primary::= variable | literal | block | primitive | "(" cascaded_expression ")".

  12. cascaded_expression::= keyword_expression #( ";" continuation).

  13. continuation::= N(message).

  14. message::= (unary_selector | binary_message | keyword_message).

    Notice that a unary selector and a keyword differ solely in the colon at the end of the latter. In Smalltalk we often use a unary method (foo) to extract data from an object and the associated keword message (foo:) to place data in the object.

    Variables

  15. variable::=(lower_case_letter #(letter|digit)) & (globalName | local_name).

    The local_names depend on the context. In a method there will be variables used in the method, plus arguments passed in the message, plus variables associated with each instance of a class. In a block the local variables are those in the block's context plus the inputs to the block.

  16. local_name::=instance_variables_of_object_s_class | variables_of_current_method| arguments_passed_to_object_in_message | inputs_to_the_block.

    The tradition is to use English words like this:

  17. traditional_variable::= first_word #later_word,
  18. first_word::=N(lower_case_letter) & English,
  19. later_word::=(upper_case_letter #lower_case_letter ) & English.

    Control Structures

    Uniquely Smalltalk does not have a special syntax for control structures. Instead the class of Boolean objects ({true, false}) and the class of Blocks ( see later ) together have messages that have methods that work like iterative and selective structures.

  20. loop::structure=See the methods whileTrue: do: .... [ smalltalk.methods.html ]
  21. selection::structure=See methods ifTrue: ifFalse: ifTrue:ifFalse: and: ifFalse:ifTrue: .... [ smalltalk.methods.html ]

    Representations of Objects in Expressions

      Literals

      Expressions contain literal representations of objects:
      LiteralClass
      123Integer
      'cat'String
      aCharacter
      #+Symbol(for a message)
      #(1 2 'cat')Array
      <120 3>Primitive command
      [ :x | x squared ]Block

    1. literal::= number | symbol | string | character_constant | bytearray | array_constant.

    2. number::= (sign|) unsigned_number,
    3. sign::= "+" | "-" ,
    4. unsigned_number::=unsigned_fraction ("e" sign unsigned_integer|),
    5. unsigned_fraction::=unsigned_integer("." unsigned_integer|),
    6. unsigned_integer::= N(digit).

    7. string::=q #(char~q | q q) q where q:="'".

    8. character_constant::="$" char.

    9. symbol::="#" N(char). Names and messages have associated symbols.

    10. byte_array::= "#" "[" N(unsigned_integer) "]".

    11. array_constant::="#" array.
    12. array::="(" #( number | symbol | string | character_constant | array) ")".

    13. primitive::="<" ( variable | primitive unsigned_integer ) # primary ">".

    14. block::= simple_block | unary_block | binary_block | ternary_block,
    15. simple_block::="[" statements "]".
    16. unary_block::="[" input_var "|" statements "]".
    17. binary_block::="[" input_var input_var "|" statements "]".
    18. ternary_block::="[" input_var input_var input_var "|" statements "]".
    19. input_var::= ":" variable.

    . . . . . . . . . ( end of section Representations of Objects in Expressions) <<Contents | End>>

    Method (for handling a message)

  22. method::= method_pattern (temporary_variables|) statements.

  23. method_pattern::=unary_selector | binary_selector argument_variable | N(keyword argument_variable).

    Notice that each method has a unique symbol associated with it made up by concatenating all the selectors and prefixing a hash_mark("#").

    Statements

  24. statements::= #( expression #("." expression) ).
  25. expression::= ("^" |) #(variable "<-") cascaded_expression.

    Selectors

  26. unary_selector::="sqrt" | "squared" | "respondsTo" | "addSubClass" | ... .
  27. unary_selector::=lower_case_letter identifier.

  28. binary_selector::="+"|"-"|"/"|"*"|"**"|... .
  29. binary_selector::= b | b b where b:= char~(letter | digit | parentheses | brackets | semicolon | period).

  30. keyword_selector::="max:" | "between:and:" | "and:" |... .
  31. keyword_selector::=N(keyword).
  32. keyword::="respondsTo:" | "max:" | "between:" | "to:" |...,
  33. keyword::=lower_case_letter identifier ":".

    Syntax of Loaded Files

    This syntax is empirical and speculative...

  34. loadable_input::=#(loadable_method | loadable_class | loadable_comment) EOF.
  35. loadable_class::= "Class" name superclass #instance_variable EOLN | "Class" previously_declared_class EOLN method EOLN "|" EOLN,

  36. loadable_method::= "Methods" class something EOLN method #( "|" EOLN method ) "]" EOLN.
  37. something::="'"initialization"'" | "'" all "'" |... ,

  38. loadable_comment::= "*" comment EOLN,

    Class Description (Not input!)

    This is an ideal class description. When a file is loaded a different but similar syntax is used (see loadable_input above).

  39. class_description::=class_heading (instance_variables|) protocol.

  40. class_heading::= "Class" class_name (colon superclass_name|).
  41. class_name::= upper_case_letter identifier.

  42. instance_variables::= "|" #instance_variable "|".

  43. protocol::= "[" method #( "|" method ) "]".

End