Commit ad711106 authored by Robert Griesemer's avatar Robert Griesemer

- 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
parent ed18e578
...@@ -4,7 +4,7 @@ The Go Programming Language Specification (DRAFT) ...@@ -4,7 +4,7 @@ The Go Programming Language Specification (DRAFT)
Robert Griesemer, Rob Pike, Ken Thompson Robert Griesemer, Rob Pike, Ken Thompson
---- ----
(September 10, 2008) (September 11, 2008)
This document is a semi-formal specification of the Go systems This document is a semi-formal specification of the Go systems
...@@ -50,6 +50,7 @@ Open issues according to gri: ...@@ -50,6 +50,7 @@ Open issues according to gri:
[ ] do we need anything on package vs file names? [ ] do we need anything on package vs file names?
[ ] need to talk about precise int/floats clearly [ ] need to talk about precise int/floats clearly
[ ] iant suggests to use abstract/precise int for len(), cap() - good idea [ ] iant suggests to use abstract/precise int for len(), cap() - good idea
(issue: what happens in len() + const - what is the type?)
--> -->
...@@ -93,6 +94,7 @@ Contents ...@@ -93,6 +94,7 @@ Contents
Expressions Expressions
Operands Operands
Qualified identifiers
Iota Iota
Composite Literals Composite Literals
Function Literals Function Literals
...@@ -205,8 +207,8 @@ Letters and digits ...@@ -205,8 +207,8 @@ Letters and digits
---- ----
letter = "A" ... "Z" | "a" ... "z" | "_" | non_ascii. letter = "A" ... "Z" | "a" ... "z" | "_" | non_ascii.
oct_digit = "0" ... "7" . decimal_digit = "0" ... "9" .
dec_digit = "0" ... "9" . octal_digit = "0" ... "7" .
hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" . hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
All non-ASCII code points are considered letters; digits are always ASCII. All non-ASCII code points are considered letters; digits are always ASCII.
...@@ -225,54 +227,66 @@ Identifiers ...@@ -225,54 +227,66 @@ Identifiers
An identifier is a name for a program entity such as a variable, a An identifier is a name for a program entity such as a variable, a
type, a function, etc. type, a function, etc.
identifier = letter { letter | dec_digit } . identifier = letter { letter | decimal_digit } .
a a
_x _x
ThisIsVariable9 ThisIsVariable9
αβ αβ
Some identifiers are predeclared (see Declarations). Some identifiers are predeclared (§Declarations).
Numeric literals Numeric literals
---- ----
Integer literals take the usual C form, except for the absence of the An integer literal represents a mathematically ideal integer constant
'U', 'L', etc. suffixes, and represent integer constants. Character of arbitrary precision, or 'ideal int'.
literals are also integer constants. Similarly, floating point
literals are also C-like, without suffixes and in decimal representation int_lit = decimal_int | octal_int | hex_int .
only. decimal_int = ( "1" ... "9" ) { decimal_digit } .
octal_int = "0" { octal_digit } .
An integer constant represents an abstract integer value of arbitrary hex_int = "0" ( "x" | "X" ) hex_digit { hex_digit } .
precision. Only when an integer constant (or arithmetic expression
formed from integer constants) is bound to a typed variable 42
or constant is it required to fit into a particular size - that of the type 0600
of the variable. In other words, integer constants and arithmetic 0xBadFace
upon them is not subject to overflow; only finalization of integer 170141183460469231731687303715884105727
constants (and constant expressions) can cause overflow.
It is an error if the value of the constant or expression cannot be A floating point literal represents a mathematically ideal floating point
represented correctly in the range of the type of the receiving constant of arbitrary precision, or 'ideal float'.
variable.
float_lit =
Floating point constants also represent an abstract, ideal floating decimals "." [ decimals ] [exponent ] |
point value that is constrained only upon assignment. decimals exponent |
"." decimals [ exponent ] .
sign = "+" | "-" . decimals = decimal_digit { decimal_digit } .
int_lit = [ sign ] unsigned_int_lit . exponent = ( "e" | "E" ) [ "+" | "-" ] decimals .
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 } . 0.
octal_int_lit = "0" { oct_digit } . 2.71828
hex_int_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } . 1.e+0
float_lit = [ sign ] ( fractional_lit | exponential_lit ) . 6.67428e-11
fractional_lit = { dec_digit } ( dec_digit "." | "." dec_digit ) { dec_digit } [ exponent ] . 1E6
exponential_lit = dec_digit { dec_digit } exponent . .25
exponent = ( "e" | "E" ) [ sign ] dec_digit { dec_digit } . .12345E+5
07 Numeric literals are unsigned. A negative constant is formed by
0xFF applying the unary prefix operator "-" (§Arithmetic operators).
-44
+3.24e-7 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 Character and string literals
...@@ -291,7 +305,7 @@ The rules are: ...@@ -291,7 +305,7 @@ The rules are:
char_lit = "'" ( unicode_value | byte_value ) "'" . char_lit = "'" ( unicode_value | byte_value ) "'" .
unicode_value = utf8_char | little_u_value | big_u_value | escaped_char . unicode_value = utf8_char | little_u_value | big_u_value | escaped_char .
byte_value = octal_byte_value | hex_byte_value . 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 . hex_byte_value = "\" "x" hex_digit hex_digit .
little_u_value = "\" "u" hex_digit hex_digit hex_digit hex_digit . little_u_value = "\" "u" hex_digit hex_digit hex_digit hex_digit .
big_u_value = big_u_value =
...@@ -349,7 +363,7 @@ do not interpret backslashes at all. ...@@ -349,7 +363,7 @@ do not interpret backslashes at all.
raw_string_lit = "`" { utf8_char } "`" . raw_string_lit = "`" { utf8_char } "`" .
interpreted_string_lit = """ { unicode_value | byte_value } """ . 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 taking the byte values formed by the successive elements of the
literal. For byte_values, these are the literal bytes; for literal. For byte_values, these are the literal bytes; for
unicode_values, these are the bytes of the UTF-8 encoding of the unicode_values, these are the bytes of the UTF-8 encoding of the
...@@ -420,8 +434,8 @@ Declarations and scope rules ...@@ -420,8 +434,8 @@ Declarations and scope rules
Every identifier in a program must be declared; some identifiers, such as "int" Every identifier in a program must be declared; some identifiers, such as "int"
and "true", are predeclared. A declaration associates an identifier and "true", are predeclared. A declaration associates an identifier
with a language entity (package, constant, type, variable, function, method, with a language entity (package, constant, type, variable, function, or method)
or label) and may specify properties of that entity such as its type. and may specify properties of that entity such as its type.
Declaration = [ "export" ] ( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) . Declaration = [ "export" ] ( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) .
...@@ -438,7 +452,7 @@ The following scope rules apply: ...@@ -438,7 +452,7 @@ The following scope rules apply:
3. Field and method identifiers may be used only to select elements 3. Field and method identifiers may be used only to select elements
from the corresponding types, and only after those types are fully from the corresponding types, and only after those types are fully
declared. In effect, the field selector operator 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 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 where "T" is not yet declared. The full declaration of "T" must be within a
block containing the forward declaration, and the forward declaration block containing the forward declaration, and the forward declaration
...@@ -446,7 +460,7 @@ The following scope rules apply: ...@@ -446,7 +460,7 @@ The following scope rules apply:
Global declarations optionally may be marked for export with the reserved word Global declarations optionally may be marked for export with the reserved word
"export". Local declarations can never be exported. "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 are made visible to clients of this package, that is, other packages that import
this package. this package.
...@@ -457,6 +471,10 @@ all structure fields and all structure and interface methods are exported also. ...@@ -457,6 +471,10 @@ all structure fields and all structure and interface methods are exported also.
export const pi float = 3.14159265 export const pi float = 3.14159265
export func Parse(source string); 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. 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. TODO: Eventually we need to be able to restrict visibility of fields and methods.
...@@ -517,9 +535,9 @@ The constant expression may be omitted, in which case the expression is ...@@ -517,9 +535,9 @@ The constant expression may be omitted, in which case the expression is
the last expression used after the reserved word "const". If no such expression the last expression used after the reserved word "const". If no such expression
exists, the constant expression cannot be omitted. 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 implicit repetition permits light-weight declaration of enumerated
values. values:
const ( const (
Sunday = iota; Sunday = iota;
...@@ -691,20 +709,19 @@ Types ...@@ -691,20 +709,19 @@ Types
A type specifies the set of values that variables of that type may A type specifies the set of values that variables of that type may
assume, and the operators that are applicable. 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 The 'static type' (or simply 'type') of a variable is the type defined by
declaration. The dynamic type of a variable is the actual type of the the variable's declaration. The 'dynamic type' of a variable is the actual
value stored in a variable at runtime. Except for variables of interface type of the value stored in a variable at runtime. Except for variables of
type, the static and dynamic type of variables is always the same. interface type, the static and dynamic type of variables is always the same.
Variables of interface type may hold values of different types during Variables of interface type may hold values of different types during
execution. However, the dynamic type of the variable is always compatible execution. However, the dynamic type of the variable is always compatible
with the static type of the variable. 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 = Type =
TypeName | ArrayType | ChannelType | InterfaceType | TypeName | ArrayType | ChannelType | InterfaceType |
FunctionType | MapType | StructType | PointerType . FunctionType | MapType | StructType | PointerType .
...@@ -736,9 +753,8 @@ Arithmetic types ...@@ -736,9 +753,8 @@ Arithmetic types
float64 the set of all valid IEEE-754 64-bit floating point numbers 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 float80 the set of all valid IEEE-754 80-bit floating point numbers
Additionally, Go declares several platform-specific type aliases: Additionally, Go declares several platform-specific type aliases; the
ushort, short, uint, int, ulong, long, float, and double. The bit bit width of these types is ``natural'' for the respective types for the
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 given platform. For instance, int is usually the same as int32 on a
32-bit architecture, or int64 on a 64-bit architecture. 32-bit architecture, or int64 on a 64-bit architecture.
...@@ -748,7 +764,17 @@ unsigned equivalents). Also, the sizes are such that short <= int <= ...@@ -748,7 +764,17 @@ unsigned equivalents). Also, the sizes are such that short <= int <=
long. Similarly, float is at least 32 bits, double is at least 64 long. Similarly, float is at least 32 bits, double is at least 64
bits, and the sizes have float <= double. 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 An arithmetic type ``ptrint'' is also defined. It is an unsigned
integer type that is the smallest natural integer type of the machine integer type that is the smallest natural integer type of the machine
...@@ -757,6 +783,16 @@ large enough to store the uninterpreted bits of a pointer value. ...@@ -757,6 +783,16 @@ large enough to store the uninterpreted bits of a pointer value.
Generally, programmers should use these types rather than the explicitly Generally, programmers should use these types rather than the explicitly
sized types to maximize portability. 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 Booleans
---- ----
...@@ -934,7 +970,7 @@ A struct is a composite type consisting of a fixed number of elements, ...@@ -934,7 +970,7 @@ A struct is a composite type consisting of a fixed number of elements,
called fields, with possibly different types. The struct type declaration called fields, with possibly different types. The struct type declaration
specifies the name and type for each field. The scope of each field identifier 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 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 [ ";" ] ] "}" . StructType = "struct" "{" [ FieldDeclList [ ";" ] ] "}" .
FieldDeclList = FieldDecl { ";" FieldDecl } . FieldDeclList = FieldDecl { ";" FieldDecl } .
...@@ -1136,12 +1172,35 @@ they implement the Lock interface as well as the File interface. ...@@ -1136,12 +1172,35 @@ they implement the Lock interface as well as the File interface.
Expressions 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 Operands
---- ----
Operands denote the elementary values in an expression.
Operand = Literal | QualifiedIdent | "(" Expression ")" . Operand = Literal | QualifiedIdent | "(" Expression ")" .
Literal = int_lit | float_lit | char_lit | string_lit | CompositeLit | FunctionLit . Literal = BasicLit | CompositeLit | FunctionLit .
BasicLit = int_lit | float_lit | char_lit | string_lit .
Qualified identifiers
----
TODO(gri) write this section
Iota Iota
...@@ -1376,17 +1435,23 @@ Operators combine operands into expressions. ...@@ -1376,17 +1435,23 @@ Operators combine operands into expressions.
unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" . unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
With the exception of shifts (see Arithmetic operators), The operand types in binary operations must be equal, with the following exceptions:
the operand types in binary operations must be the same.
For instance, signed and unsigned integer values cannot be - The right operand in a shift operation must be
mixed in an expression, and there is no implicit conversion an unsigned int type (§Arithmetic operators).
from integer to floating point types.
- 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. Unary operators have the highest precedence.
There are six precedence levels for binary operators: There are six precedence levels for binary operators:
multiplication operators bind strongest, followed by addition multiplication operators bind strongest, followed by addition
operators, comparison operators, communication operators, "&&" (logical and), operators, comparison operators, communication operators,
and finally "||" (logical or) with the lowest precedence: "&&" (logical and), and finally "||" (logical or) with the
lowest precedence:
Precedence Operator Precedence Operator
6 * / % << >> & 6 * / % << >> &
...@@ -1663,7 +1728,7 @@ Statements ...@@ -1663,7 +1728,7 @@ Statements
Statements control execution. Statements control execution.
Statement = Statement =
Declaration | Declaration | LabelDecl |
SimpleStat | GoStat | ReturnStat | BreakStat | ContinueStat | GotoStat | SimpleStat | GoStat | ReturnStat | BreakStat | ContinueStat | GotoStat |
Block | IfStat | SwitchStat | SelectStat | ForStat | RangeStat | Block | IfStat | SwitchStat | SelectStat | ForStat | RangeStat |
...@@ -2097,7 +2162,7 @@ A function declaration declares an identifier of type function. ...@@ -2097,7 +2162,7 @@ A function declaration declares an identifier of type function.
return y; 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; func MakeNode(left, right *Node) *Node;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment