(* l05 - expressions with relations *) program = statement { ';' statement } '.' . statement = [ declaration | '!' expression ] . declaration = id ( '=' constexpr | ':=' expression ) . constexpr = number | id . expression = simplexpr [ relop simplexpr ] . simplexpr = [ '+' | '-' ] term { addop term } . term = factor { mulop factor } . factor = number | id | '(' expression ')' | '~' factor . relop = '=' | '#' | '<>' | '<' | '<=' | '>' | '>=' . addop = '+' | '-' | '|' . mulop = '*' | '/' | '&' . (* l05 = l03 + relations. Back on stack machine. State of the l03 machine was stack and variables only. There was no "program" because l03 allowed for immediate execution. Before making instruction storing a requirement (control structures, procedures) I introduce the relation (something like condition in PL/0) as operations of lowest order. Without control structures, its only use is in statements. Then, relations must be expressions (unlike PL/0), and boolean arithmetics can also be introduced. Automatic types result in ugly code; but at least it seems to work. '!TRUE<=FALSE.' produces: Comp.Debug: ac top-1 top Comp.Debug: 0 : Val 1 Comp.Debug: 1 1: Val 0 Comp.Debug: 2 1 0: Leq Comp.Debug: 1 0: WrB FALSE Retyping (of variables) is allowed only for simplicity (parser code). It will disappear with the next step. 2010-06-05, v01: Store introduced. Still, generator and interpreter are both implemented in Comp. 2010-07-11: Just a remark on evaluation of relations, i.e. (boolean) expressions: In my implementation, every simplexpr is evaluated (at runtime). This is in contrast to the usual coding of 'a OR b' as 'IF a THEN TRUE ELSE b'. But in l05 there are no side effects, so my coding yields correct results, although it wastes some CPU cycles (and program space, now that we have a store). *)