- rewrote section on numeric literals (grammar easier to read,
separate between ints and floats, added language regarding the
type of numeric literals)
- added language with respect to the scope of labels
- introduced ideal types for the purpose of the spec
- added language to expressions, operands
- added some more formal language about ideal type conversion
  (probably not 100% correct yet)

R=r
DELTA=145  (69 added, 4 deleted, 72 changed)
OCL=15165
CL=15186
diff --git a/doc/go_spec.txt b/doc/go_spec.txt
index ddf1af4..0975bc0 100644
--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -4,7 +4,7 @@
 Robert Griesemer, Rob Pike, Ken Thompson
 
 ----
-(September 10, 2008)
+(September 11, 2008)
 
 
 This document is a semi-formal specification of the Go systems
@@ -50,6 +50,7 @@
 [ ] do we need anything on package vs file names?
 [ ] need to talk about precise int/floats clearly
 [ ] iant suggests to use abstract/precise int for len(), cap() - good idea
+    (issue: what happens in len() + const - what is the type?)
 
 -->
 
@@ -93,7 +94,8 @@
 
 	Expressions
 		Operands
-			Iota
+			Qualified identifiers
+				Iota
 			Composite Literals
 			Function Literals
 
@@ -204,10 +206,10 @@
 Letters and digits
 ----
 
-	letter    = "A" ... "Z" | "a" ... "z" | "_" | non_ascii.
-	oct_digit = "0" ... "7" .
-	dec_digit = "0" ... "9" .
-	hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
+	letter        = "A" ... "Z" | "a" ... "z" | "_" | non_ascii.
+	decimal_digit = "0" ... "9" .
+	octal_digit   = "0" ... "7" .
+	hex_digit     = "0" ... "9" | "A" ... "F" | "a" ... "f" .
 
 All non-ASCII code points are considered letters; digits are always ASCII.
 
@@ -225,54 +227,66 @@
 An identifier is a name for a program entity such as a variable, a
 type, a function, etc.
 
-	identifier = letter { letter | dec_digit } .
+	identifier = letter { letter | decimal_digit } .
 
 	a
 	_x
 	ThisIsVariable9
 	αβ
 
-Some identifiers are predeclared (see Declarations).
+Some identifiers are predeclared (§Declarations).
 
 
 Numeric literals
 ----
 
-Integer literals take the usual C form, except for the absence of the
-'U', 'L', etc. suffixes, and represent integer constants.  Character
-literals are also integer constants.  Similarly, floating point
-literals are also C-like, without suffixes and in decimal representation
-only.
+An integer literal represents a mathematically ideal integer constant
+of arbitrary precision, or 'ideal int'.
 
-An integer constant represents an abstract integer value of arbitrary
-precision.  Only when an integer constant (or arithmetic expression
-formed from integer constants) is bound to a typed variable
-or constant is it required to fit into a particular size - that of the type
-of the variable.  In other words, integer constants and arithmetic
-upon them is not subject to overflow; only finalization of integer
-constants (and constant expressions) can cause overflow.
-It is an error if the value of the constant or expression cannot be
-represented correctly in the range of the type of the receiving
-variable.
+	int_lit     = decimal_int | octal_int | hex_int .
+	decimal_int = ( "1" ... "9" ) { decimal_digit } .
+	octal_int   = "0" { octal_digit } .
+	hex_int     = "0" ( "x" | "X" ) hex_digit { hex_digit } .
 
-Floating point constants also represent an abstract, ideal floating
-point value that is constrained only upon assignment.
+	42
+	0600
+	0xBadFace
+	170141183460469231731687303715884105727
 
-	sign = "+" | "-" .
-	int_lit = [ sign ] unsigned_int_lit .
-	unsigned_int_lit = decimal_int_lit | octal_int_lit | hex_int_lit .
-	decimal_int_lit = ( "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ) { dec_digit } .
-	octal_int_lit = "0" { oct_digit } .
-	hex_int_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } .
-	float_lit =  [ sign ] ( fractional_lit | exponential_lit ) .
-	fractional_lit = { dec_digit } ( dec_digit "." | "." dec_digit ) { dec_digit } [ exponent ] .
-	exponential_lit = dec_digit { dec_digit } exponent .
-	exponent = ( "e" | "E" ) [ sign ] dec_digit { dec_digit } .
+A floating point literal represents a mathematically ideal floating point
+constant of arbitrary precision, or 'ideal float'.
 
-	07
-	0xFF
-	-44
-	+3.24e-7
+	float_lit =
+		decimals "." [ decimals ] [exponent ] |
+		decimals exponent |
+		"." decimals [ exponent ] .
+	decimals = decimal_digit { decimal_digit } .
+	exponent = ( "e" | "E" ) [ "+" | "-" ] decimals .
+
+	0.
+	2.71828
+	1.e+0
+	6.67428e-11
+	1E6
+	.25
+	.12345E+5
+
+Numeric literals are unsigned. A negative constant is formed by
+applying the unary prefix operator "-" (§Arithmetic operators).
+
+An 'ideal number' is either an 'ideal int' or an 'ideal float'.
+
+Only when an ideal number (or an arithmetic expression formed
+solely from ideal numbers) is bound to a variable or used in an expression
+or constant of fixed-size integers or floats it is required to fit
+a particular size.  In other words, ideal numbers and arithmetic
+upon them are not subject to overflow; only use of them in assignments
+or expressions involving fixed-size numbers may cause overflow, and thus
+an error (§Expressions).
+
+Implementation restriction: A compiler may implement ideal numbers
+by choosing a "sufficiently large" internal representation of such
+numbers.
 
 
 Character and string literals
@@ -291,7 +305,7 @@
 	char_lit = "'" ( unicode_value | byte_value ) "'" .
 	unicode_value = utf8_char | little_u_value | big_u_value | escaped_char .
 	byte_value = octal_byte_value | hex_byte_value .
-	octal_byte_value = "\" oct_digit oct_digit oct_digit .
+	octal_byte_value = "\" octal_digit octal_digit octal_digit .
 	hex_byte_value = "\" "x" hex_digit hex_digit .
 	little_u_value = "\" "u" hex_digit hex_digit hex_digit hex_digit .
 	big_u_value =
@@ -349,7 +363,7 @@
 	raw_string_lit = "`" { utf8_char } "`" .
 	interpreted_string_lit = """ { unicode_value | byte_value } """ .
 
-A string literal has type 'string'.  Its value is constructed by
+A string literal has type "string".  Its value is constructed by
 taking the byte values formed by the successive elements of the
 literal.  For byte_values, these are the literal bytes; for
 unicode_values, these are the bytes of the UTF-8 encoding of the
@@ -420,8 +434,8 @@
 
 Every identifier in a program must be declared; some identifiers, such as "int"
 and "true", are predeclared. A declaration associates an identifier
-with a language entity (package, constant, type, variable, function, method,
-or label) and may specify properties of that entity such as its type.
+with a language entity (package, constant, type, variable, function, or method)
+and may specify properties of that entity such as its type.
 
 	Declaration = [ "export" ] ( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) .
 
@@ -438,7 +452,7 @@
 	3. Field and method identifiers may be used only to select elements
 	   from the corresponding types, and only after those types are fully
 	   declared.  In effect, the field selector operator
-	   '.' temporarily re-opens the scope of such identifiers (see Expressions).
+	   "." temporarily re-opens the scope of such identifiers (§Expressions).
 	4. Forward declaration: A type of the form "*T" may be mentioned at a point
 	   where "T" is not yet declared. The full declaration of "T" must be within a
 	   block containing the forward declaration, and the forward declaration
@@ -446,7 +460,7 @@
 
 Global declarations optionally may be marked for export with the reserved word
 "export". Local declarations can never be exported.
-All identifiers (and only those identifiers) declared in exported declarations
+Identifiers declared in exported declarations (and no other identifiers)
 are made visible to clients of this package, that is, other packages that import
 this package.
 
@@ -457,6 +471,10 @@
 	export const pi float = 3.14159265
 	export func Parse(source string);
 
+The scope of a label 'x' is the entire block of the surrounding function (excluding
+nested functions that redeclare 'x'); label scopes do not intersect with any other
+scopes. Within a function a label 'x' may only be declared once (§Labels).
+
 Note that at the moment the old-style export via ExportDecl is still supported.
 
 TODO: Eventually we need to be able to restrict visibility of fields and methods.
@@ -517,9 +535,9 @@
 the last expression used after the reserved word "const". If no such expression
 exists, the constant expression cannot be omitted.
 
-Together with the 'iota' constant generator (described later),
+Together with the "iota" constant generator (described later),
 implicit repetition permits light-weight declaration of enumerated
-values.
+values:
 
 	const (
 		Sunday = iota;
@@ -691,20 +709,19 @@
 A type specifies the set of values that variables of that type may
 assume, and the operators that are applicable.
 
-There are basic types and composite types.
+There are basic types and composite types. Basic types are predeclared.
+Composite types are arrays, maps, channels, structures, functions, pointers,
+and interfaces. They are constructed from other (basic or composite) types.
 
-The static type of a variable is the type defined by the variable's
-declaration. The dynamic type of a variable is the actual type of the
-value stored in a variable at runtime. Except for variables of interface
-type, the static and dynamic type of variables is always the same.
+The 'static type' (or simply 'type') of a variable is the type defined by
+the variable's declaration. The 'dynamic type' of a variable is the actual
+type of the value stored in a variable at runtime. Except for variables of
+interface type, the static and dynamic type of variables is always the same.
 
 Variables of interface type may hold values of different types during
 execution. However, the dynamic type of the variable is always compatible
 with the static type of the variable.
 
-Types may be composed from other types by assembling arrays, maps,
-channels, structures, and functions. They are called composite types.
-
 	Type =
 		TypeName | ArrayType | ChannelType | InterfaceType |
 		FunctionType | MapType | StructType | PointerType .
@@ -736,9 +753,8 @@
 	float64  the set of all valid IEEE-754 64-bit floating point numbers
 	float80  the set of all valid IEEE-754 80-bit floating point numbers
 
-Additionally, Go declares several platform-specific type aliases:
-ushort, short, uint, int, ulong, long, float, and double.  The bit
-width of these types is ``natural'' for the respective types for the
+Additionally, Go declares several platform-specific type aliases; the
+bit width of these types is ``natural'' for the respective types for the
 given platform.  For instance, int is usually the same as int32 on a
 32-bit architecture, or int64 on a 64-bit architecture.
 
@@ -748,7 +764,17 @@
 long.  Similarly, float is at least 32 bits, double is at least 64
 bits, and the sizes have float <= double.
 
-Also, ``byte'' is an alias for uint8.
+	byte     alias for uint8
+	ushort	 uint16 <= ushort <= uint
+	uint     uint32 <= uint <= ulong
+	ulong    uint64 <= ulong
+
+	short	 int16 <= short <= int
+	int      int32 <= int <= long
+	long     int64 <= long
+
+	float	 float32 <= float <= double
+	double   float64 <= double
 
 An arithmetic type ``ptrint'' is also defined.  It is an unsigned
 integer type that is the smallest natural integer type of the machine
@@ -757,6 +783,16 @@
 Generally, programmers should use these types rather than the explicitly
 sized types to maximize portability.
 
+Finally, for the purpose of explaining the rules of expressions (§Expressions),
+there are three ideal numeric types:
+
+	'ideal int'     the set of all ideal ints
+	'ideal float'   the set of all ideal floats
+	'ideal number'  the union of ideal_int and ideal_float
+	
+The type of an integer or character literal is "ideal_int"
+and the type of a floating point literal is "ideal_float".
+
 
 Booleans
 ----
@@ -934,7 +970,7 @@
 called fields, with possibly different types. The struct type declaration
 specifies the name and type for each field. The scope of each field identifier
 extends from the point of the declaration to the end of the struct type, but
-it is also visible within field selectors (see Primary Expressions).
+it is also visible within field selectors (§Primary Expressions).
 
 	StructType = "struct" "{" [ FieldDeclList [ ";" ] ] "}" .
 	FieldDeclList = FieldDecl { ";" FieldDecl } .
@@ -1136,14 +1172,37 @@
 Expressions
 ----
 
+An expression specifies the computation of a value via the application of
+operators and function invocations on operands. An expression has a value and
+a type.
+
+An expression may be of ideal numeric type. The type of such expressions is
+implicitly converted into the 'expected type' required for the expression.
+The conversion is legal if the (ideal) expression value is a member of the
+set represented by the expected type. Otherwise the expression is erroneous.
+
+For instance, if the expected type is int32, any ideal_int or ideal_float
+value which fits into an int32 without loss of precision can be legally converted.
+Along the same lines, a negative ideal integer cannot be converted into a uint
+without loss of the sign; such a conversion is illegal.
+
 
 Operands
 ----
-	
-	Operand = Literal | QualifiedIdent | "(" Expression ")" .
-	Literal = int_lit | float_lit | char_lit | string_lit | CompositeLit | FunctionLit .
-	
-	
+
+Operands denote the elementary values in an expression.
+
+	Operand  = Literal | QualifiedIdent | "(" Expression ")" .
+	Literal  = BasicLit | CompositeLit | FunctionLit .
+	BasicLit = int_lit | float_lit | char_lit | string_lit .
+
+
+Qualified identifiers
+----
+
+TODO(gri) write this section
+
+
 Iota
 ----
 
@@ -1376,17 +1435,23 @@
 
 	unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
 
-With the exception of shifts (see Arithmetic operators),
-the operand types in binary operations must be the same.
-For instance, signed and unsigned integer values cannot be
-mixed in an expression, and there is no implicit conversion
-from integer to floating point types.
+The operand types in binary operations must be equal, with the following exceptions:
+
+	- The right operand in a shift operation must be
+	  an unsigned int type (§Arithmetic operators).
+
+	- Otherwise, an operand of ideal_number type is
+	  converted into the type of the other operand (§Expression).
+	  
+	- If both operands are ideal numbers, the conversion is to ideal_float
+	  if one of the operand types is ideal_float (relevant for "/" and "%").
 
 Unary operators have the highest precedence.
 There are six precedence levels for binary operators:
 multiplication operators bind strongest, followed by addition
-operators, comparison operators, communication operators, "&&" (logical and),
-and finally "||" (logical or) with the lowest precedence:
+operators, comparison operators, communication operators,
+"&&" (logical and), and finally "||" (logical or) with the
+lowest precedence:
 
 	Precedence    Operator
 		6             *  /  %  <<  >>  &
@@ -1663,7 +1728,7 @@
 Statements control execution.
 
 	Statement =
-		Declaration |
+		Declaration | LabelDecl |
 		SimpleStat | GoStat | ReturnStat | BreakStat | ContinueStat | GotoStat |
 		Block | IfStat | SwitchStat | SelectStat | ForStat | RangeStat |
 	
@@ -2097,7 +2162,7 @@
 		return y;
 	}
 
-A function declaration without a body serves as a forward declaration:
+A function declaration without a block serves as a forward declaration:
 
 	func MakeNode(left, right *Node) *Node;