mirror of
https://github.com/golang/go
synced 2024-11-21 23:44:39 -07:00
- updated docs
SVN=111539
This commit is contained in:
parent
719a06fd97
commit
28590a0abb
235
doc/go_lang.txt
235
doc/go_lang.txt
@ -17,8 +17,8 @@ The design is motivated by the following guidelines:
|
|||||||
- strongly typed
|
- strongly typed
|
||||||
- concise syntax avoiding repetition
|
- concise syntax avoiding repetition
|
||||||
- few, orthogonal, and general concepts
|
- few, orthogonal, and general concepts
|
||||||
- excellent support for threading and interprocess communication
|
- support for threading and interprocess communication
|
||||||
- efficient garbage collection
|
- garbage collection
|
||||||
- container library written in Go
|
- container library written in Go
|
||||||
- reasonably efficient (C ballpark)
|
- reasonably efficient (C ballpark)
|
||||||
|
|
||||||
@ -34,12 +34,11 @@ individual identifiers visible to other files by marking them as
|
|||||||
exported; there is no "header file".
|
exported; there is no "header file".
|
||||||
|
|
||||||
A package collects types, constants, functions, and so on into a named
|
A package collects types, constants, functions, and so on into a named
|
||||||
entity that may be imported to enable its constituents be used in
|
entity that may be exported to enable its constituents be used in
|
||||||
another compilation unit.
|
another compilation unit.
|
||||||
|
|
||||||
Because there are no header files, all identifiers in a package are either
|
Because there are no header files, all identifiers in a package are either
|
||||||
declared explicitly within the package or, in certain cases, arise from an
|
declared explicitly within the package or arise from an import statement.
|
||||||
import statement.
|
|
||||||
|
|
||||||
Scoping is essentially the same as in C.
|
Scoping is essentially the same as in C.
|
||||||
|
|
||||||
@ -64,20 +63,9 @@ still under development.
|
|||||||
|
|
||||||
Typing, polymorphism, and object-orientation
|
Typing, polymorphism, and object-orientation
|
||||||
|
|
||||||
Go programs are strongly typed: each program entity has a static
|
Go programs are strongly typed. Certain expressions, in particular map
|
||||||
type known at compile time. Variables also have a dynamic type, which
|
and channel accesses, can also be polymorphic. The language provides
|
||||||
is the type of the value they hold at run-time. Usually, the
|
mechanisms to make use of such polymorphic values type-safe.
|
||||||
dynamic and the static type of a variable are identical, except for
|
|
||||||
variables of interface type. In that case the dynamic type of the
|
|
||||||
variable is a pointer to a structure that implements the variable's
|
|
||||||
(static) interface type. There may be many different structures
|
|
||||||
implementing an interface and thus the dynamic type of such variables
|
|
||||||
is generally not known at compile time. Such variables are called
|
|
||||||
polymorphic.
|
|
||||||
|
|
||||||
Also, certain expressions, in particular map and channel accesses,
|
|
||||||
can also be polymorphic. The language provides mechanisms to
|
|
||||||
make use of such polymorphic values type-safe.
|
|
||||||
|
|
||||||
Interface types are the mechanism to support an object-oriented
|
Interface types are the mechanism to support an object-oriented
|
||||||
programming style. Different interface types are independent of each
|
programming style. Different interface types are independent of each
|
||||||
@ -130,7 +118,8 @@ language support.
|
|||||||
|
|
||||||
Values and references
|
Values and references
|
||||||
|
|
||||||
Unless accessing expliciting through a pointer, all objects are values.
|
All objects have value semantics, but its contents may be accessed
|
||||||
|
through different pointers referring to the same object.
|
||||||
For example, when calling a function with an array, the array is
|
For example, when calling a function with an array, the array is
|
||||||
passed by value, possibly by making a copy. To pass a reference,
|
passed by value, possibly by making a copy. To pass a reference,
|
||||||
one must explicitly pass a pointer to the array. For arrays in
|
one must explicitly pass a pointer to the array. For arrays in
|
||||||
@ -151,9 +140,9 @@ Here is a complete example Go program that implements a concurrent prime sieve:
|
|||||||
============================
|
============================
|
||||||
package Main
|
package Main
|
||||||
|
|
||||||
// Send the sequence 2, 3, 4, ... to channel 'c'.
|
// Send the sequence 2, 3, 4, ... to channel 'ch'.
|
||||||
func Generate(ch *chan< int) {
|
func Generate(ch *chan> int) {
|
||||||
for i := 2; true; i++ {
|
for i := 2; ; i++ {
|
||||||
>ch = i; // Send 'i' to channel 'ch'.
|
>ch = i; // Send 'i' to channel 'ch'.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,7 +150,7 @@ func Generate(ch *chan< int) {
|
|||||||
// Copy the values from channel 'in' to channel 'out',
|
// Copy the values from channel 'in' to channel 'out',
|
||||||
// removing those divisible by 'prime'.
|
// removing those divisible by 'prime'.
|
||||||
func Filter(in *chan< int, out *chan> int, prime int) {
|
func Filter(in *chan< int, out *chan> int, prime int) {
|
||||||
while true {
|
for ; ; {
|
||||||
i := <in; // Receive value of new variable 'i' from 'in'.
|
i := <in; // Receive value of new variable 'i' from 'in'.
|
||||||
if i % prime != 0 {
|
if i % prime != 0 {
|
||||||
>out = i; // Send 'i' to channel 'out'.
|
>out = i; // Send 'i' to channel 'out'.
|
||||||
@ -173,7 +162,7 @@ func Filter(in *chan< int, out *chan> int, prime int) {
|
|||||||
func Sieve() {
|
func Sieve() {
|
||||||
ch := new(chan int); // Create a new channel.
|
ch := new(chan int); // Create a new channel.
|
||||||
go Generate(ch); // Start Generate() as a subprocess.
|
go Generate(ch); // Start Generate() as a subprocess.
|
||||||
while true {
|
for ; ; {
|
||||||
prime := <ch;
|
prime := <ch;
|
||||||
printf("%d\n", prime);
|
printf("%d\n", prime);
|
||||||
ch1 := new(chan int);
|
ch1 := new(chan int);
|
||||||
@ -248,14 +237,14 @@ hex_digit = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' |
|
|||||||
'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'e' | 'E' | 'f' | 'F' } .
|
'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'e' | 'E' | 'f' | 'F' } .
|
||||||
letter = 'A' | 'a' | ... 'Z' | 'z' | '_' .
|
letter = 'A' | 'a' | ... 'Z' | 'z' | '_' .
|
||||||
|
|
||||||
For simplicity, letters and digits are ASCII. We may expand this to allow
|
For simplicity, letters and digits are ASCII. We may in time allow
|
||||||
Unicode definitions of letters and digits.
|
Unicode identifiers.
|
||||||
|
|
||||||
|
|
||||||
Identifiers
|
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. An identifier must not be a reserved word.
|
||||||
|
|
||||||
identifier = letter { letter | decimal_digit } .
|
identifier = letter { letter | decimal_digit } .
|
||||||
|
|
||||||
@ -304,7 +293,7 @@ architecture, or int64 on a 64-bit architecture. These types are by
|
|||||||
definition platform-specific and should be used with the appropriate
|
definition platform-specific and should be used with the appropriate
|
||||||
caution.
|
caution.
|
||||||
|
|
||||||
Two predeclared identifiers, 'true' and 'false', represent the
|
Two reserved words, 'true' and 'false', represent the
|
||||||
corresponding boolean constant values.
|
corresponding boolean constant values.
|
||||||
|
|
||||||
|
|
||||||
@ -509,7 +498,7 @@ elements of an array is called its length. The elements of an array
|
|||||||
are designated by indices which are integers between 0 and the length
|
are designated by indices which are integers between 0 and the length
|
||||||
- 1.
|
- 1.
|
||||||
|
|
||||||
An array type specifies a set of arrays with a given element type and
|
An array type specifies arrays with a given element type and
|
||||||
an optional array length. The array length must be a (compile-time)
|
an optional array length. The array length must be a (compile-time)
|
||||||
constant expression, if present. Arrays without length specification
|
constant expression, if present. Arrays without length specification
|
||||||
are called dynamic arrays. A dynamic array must not contain other dynamic
|
are called dynamic arrays. A dynamic array must not contain other dynamic
|
||||||
@ -522,6 +511,7 @@ ArrayLength = Expression.
|
|||||||
ElementType = Type.
|
ElementType = Type.
|
||||||
|
|
||||||
[] uint8
|
[] uint8
|
||||||
|
[2*n] int
|
||||||
[64] struct { x, y: int32; }
|
[64] struct { x, y: int32; }
|
||||||
[1000][1000] float64
|
[1000][1000] float64
|
||||||
|
|
||||||
@ -544,13 +534,15 @@ called (key, value) pairs. For a given map,
|
|||||||
the keys and values must each be of a specific type.
|
the keys and values must each be of a specific type.
|
||||||
Upon creation, a map is empty and values may be added and removed
|
Upon creation, a map is empty and values may be added and removed
|
||||||
during execution. The number of entries in a map is called its length.
|
during execution. The number of entries in a map is called its length.
|
||||||
|
A map whose value type is 'any' can store values of all types.
|
||||||
|
|
||||||
MapType = 'map' '[' KeyType ']' ValueType .
|
MapType = 'map' '[' KeyType ']' ValueType .
|
||||||
KeyType = Type .
|
KeyType = Type .
|
||||||
ValueType = Type .
|
ValueType = Type | 'any' .
|
||||||
|
|
||||||
map [string] int
|
map [string] int
|
||||||
map [struct { pid int; name string }] *chan Buffer
|
map [struct { pid int; name string }] *chan Buffer
|
||||||
|
map [string] any
|
||||||
|
|
||||||
|
|
||||||
Map Literals
|
Map Literals
|
||||||
@ -595,11 +587,14 @@ Struct literals represent struct constants. They comprise a list of
|
|||||||
expressions that represent the individual fields of a struct. The
|
expressions that represent the individual fields of a struct. The
|
||||||
individual expressions must match those of the specified struct type.
|
individual expressions must match those of the specified struct type.
|
||||||
|
|
||||||
StructLit = StructType '{' [ ExpressionList ] '}' .
|
StructLit = StructType '(' [ ExpressionList ] ')' .
|
||||||
StructType = TypeName .
|
StructType = TypeName .
|
||||||
|
|
||||||
The type name must be that of a defined struct type.
|
The type name must be that of a defined struct type.
|
||||||
|
|
||||||
|
Point(2, 3)
|
||||||
|
ColoredPoint(4, 4, "green")
|
||||||
|
|
||||||
|
|
||||||
Pointer types
|
Pointer types
|
||||||
|
|
||||||
@ -626,12 +621,12 @@ Upon creation, a channel can be used both to send and to receive; it
|
|||||||
may be restricted only to send or to receive; such a restricted channel
|
may be restricted only to send or to receive; such a restricted channel
|
||||||
is called a 'send channel' or a 'receive channel'.
|
is called a 'send channel' or a 'receive channel'.
|
||||||
|
|
||||||
ChannelType = 'chan' [ '<' | '>' ] [ Type ] .
|
ChannelType = 'chan' [ '<' | '>' ] ValueType .
|
||||||
|
|
||||||
chan // a generic channel
|
chan any // a generic channel
|
||||||
chan int // a channel that can exchange only ints
|
chan int // a channel that can exchange only ints
|
||||||
chan> float // a channel that can only be used to send floats
|
chan> float // a channel that can only be used to send floats
|
||||||
chan< // a channel that can receive (only) values of any type
|
chan< any // a channel that can receive (only) values of any type
|
||||||
|
|
||||||
Channel variables always have type pointer to channel.
|
Channel variables always have type pointer to channel.
|
||||||
It is an error to attempt to dereference a channel pointer.
|
It is an error to attempt to dereference a channel pointer.
|
||||||
@ -682,6 +677,8 @@ Block = '{' [ StatementList ] '}' .
|
|||||||
|
|
||||||
A function literal can be invoked
|
A function literal can be invoked
|
||||||
or assigned to a variable of the corresponding function pointer type.
|
or assigned to a variable of the corresponding function pointer type.
|
||||||
|
For now, a function literal can reference only its parameters, global
|
||||||
|
variables, and variables declared within the function literal.
|
||||||
|
|
||||||
// Function literal
|
// Function literal
|
||||||
func (a, b int, z float) bool { return a*b < int(z); }
|
func (a, b int, z float) bool { return a*b < int(z); }
|
||||||
@ -700,10 +697,13 @@ a method indicates the type of the struct by declaring a receiver of type
|
|||||||
|
|
||||||
the declaration
|
the declaration
|
||||||
|
|
||||||
func (p *Point) distance(float scale) float { return scale * (p.x*p.x + p.y*p.y) }
|
func (p *Point) distance(float scale) float {
|
||||||
|
return scale * (p.x*p.x + p.y*p.y);
|
||||||
|
}
|
||||||
|
|
||||||
creates a method of type Point. Note that methods are not declared
|
creates a method of type Point. Note that methods are not declared
|
||||||
within their struct type declaration. They may appear anywhere.
|
within their struct type declaration. They may appear anywhere and
|
||||||
|
may be forward-declared for commentary.
|
||||||
|
|
||||||
When invoked, a method behaves like a function whose first argument
|
When invoked, a method behaves like a function whose first argument
|
||||||
is the receiver, but at the call site the receiver is bound to the method
|
is the receiver, but at the call site the receiver is bound to the method
|
||||||
@ -736,9 +736,9 @@ MethodDecl = identifier Parameters [ Result ] ';' .
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Any struct that has, as a subset, the methods of that interface is
|
Any struct whose interface has, possibly as a subset, the complete
|
||||||
said to implement the interface. For instance, if two struct types
|
set of methods of an interface I is said to implement interface I.
|
||||||
S1 and S2 have the methods
|
For instance, if two struct types S1 and S2 have the methods
|
||||||
|
|
||||||
func (p *T) Read(b Buffer) bool { return ... }
|
func (p *T) Read(b Buffer) bool { return ... }
|
||||||
func (p *T) Write(b Buffer) bool { return ... }
|
func (p *T) Write(b Buffer) bool { return ... }
|
||||||
@ -860,7 +860,8 @@ Function and method declarations
|
|||||||
|
|
||||||
Functions and methods have a special declaration syntax, slightly
|
Functions and methods have a special declaration syntax, slightly
|
||||||
different from the type syntax because an identifier must be present
|
different from the type syntax because an identifier must be present
|
||||||
in the signature.
|
in the signature. For now, functions and methods can only be declared
|
||||||
|
at the global level.
|
||||||
|
|
||||||
FunctionDecl = 'func' NamedSignature ( ';' | Block ) .
|
FunctionDecl = 'func' NamedSignature ( ';' | Block ) .
|
||||||
NamedSignature = [ Receiver ] identifier Parameters [ Result ] .
|
NamedSignature = [ Receiver ] identifier Parameters [ Result ] .
|
||||||
@ -900,7 +901,7 @@ Functions and methods can be forward declared by omitting the body:
|
|||||||
|
|
||||||
Export declarations
|
Export declarations
|
||||||
|
|
||||||
Globally declared identifiers may be exported, thus making the
|
Global identifiers may be exported, thus making the
|
||||||
exported identifer visible outside the package. Another package may
|
exported identifer visible outside the package. Another package may
|
||||||
then import the identifier to use it.
|
then import the identifier to use it.
|
||||||
|
|
||||||
@ -966,10 +967,11 @@ can be simplified to
|
|||||||
Expression = Conjunction { '||' Conjunction }.
|
Expression = Conjunction { '||' Conjunction }.
|
||||||
Conjunction = Comparison { '&&' Comparison }.
|
Conjunction = Comparison { '&&' Comparison }.
|
||||||
Comparison = SimpleExpr [ relation SimpleExpr ].
|
Comparison = SimpleExpr [ relation SimpleExpr ].
|
||||||
relation = '==' | '!=' | '<' | '<=' | '>' | '>='.
|
|
||||||
SimpleExpr = Term { add_op Term }.
|
SimpleExpr = Term { add_op Term }.
|
||||||
add_op = '+' | '-' | '|' | '^'.
|
|
||||||
Term = Operand { mul_op Operand }.
|
Term = Operand { mul_op Operand }.
|
||||||
|
|
||||||
|
relation = '==' | '!=' | '<' | '<=' | '>' | '>='.
|
||||||
|
add_op = '+' | '-' | '|' | '^'.
|
||||||
mul_op = '*' | '/' | '%' | '<<' | '>>' | '&'.
|
mul_op = '*' | '/' | '%' | '<<' | '>>' | '&'.
|
||||||
|
|
||||||
The corresponding precedence hierarchy is as follows:
|
The corresponding precedence hierarchy is as follows:
|
||||||
@ -996,13 +998,14 @@ and
|
|||||||
(a / b) is "truncated towards zero".
|
(a / b) is "truncated towards zero".
|
||||||
|
|
||||||
The shift operators implement arithmetic shifts for signed integers,
|
The shift operators implement arithmetic shifts for signed integers,
|
||||||
and logical shifts for unsigned integers.
|
and logical shifts for unsigned integers. The property of negative
|
||||||
|
shift counts are undefined.
|
||||||
|
|
||||||
There are no implicit type conversions except for
|
There are no implicit type conversions except for
|
||||||
constants and literals. In particular, unsigned and signed integers
|
constants and literals. In particular, unsigned and signed integers
|
||||||
cannot be mixed in an expression w/o explicit casting.
|
cannot be mixed in an expression w/o explicit casting.
|
||||||
|
|
||||||
Unary '^' corresponds to C '~' (bitwise negate).
|
Unary '^' corresponds to C '~' (bitwise complement).
|
||||||
|
|
||||||
|
|
||||||
Statements
|
Statements
|
||||||
@ -1016,7 +1019,7 @@ Statement =
|
|||||||
GoStat |
|
GoStat |
|
||||||
ReturnStat |
|
ReturnStat |
|
||||||
IfStat | SwitchStat |
|
IfStat | SwitchStat |
|
||||||
WhileStat | ForStat | RangeStat |
|
ForStat | RangeStat |
|
||||||
BreakStat | ContinueStat | GotoStat | LabelStat .
|
BreakStat | ContinueStat | GotoStat | LabelStat .
|
||||||
|
|
||||||
|
|
||||||
@ -1066,22 +1069,39 @@ or an array indexing.
|
|||||||
|
|
||||||
A tuple assignment assigns the individual elements of a multi-valued operation,
|
A tuple assignment assigns the individual elements of a multi-valued operation,
|
||||||
such function evaluation or some channel and map operations, into individual
|
such function evaluation or some channel and map operations, into individual
|
||||||
variables. Tuple assignment is simultaneous.
|
variables. For instance, a tuple assignment such as
|
||||||
For example,
|
|
||||||
|
v1, v2, v3 = e1, e2, e3
|
||||||
|
|
||||||
|
assigns the expressions e1, e2, e3 to temporaries and then assigns the temporaries
|
||||||
|
to the variables v1, v2, v3. Thus
|
||||||
|
|
||||||
a, b = b, a
|
a, b = b, a
|
||||||
|
|
||||||
exchanges the values of a and b.
|
exchanges the values of a and b. The tuple assignment
|
||||||
|
|
||||||
x, y = f()
|
x, y = f()
|
||||||
|
|
||||||
|
calls the function f, which must return 2 values and assigns them to x and y.
|
||||||
|
As a special case, retrieving a value from a map, when written as a two-element
|
||||||
|
tuple assignment, assign a value and a boolean. If the value is present in the map,
|
||||||
|
the value is assigned and the second, boolean variable is set to true. Otherwise,
|
||||||
|
the variable is unchanged, and the boolean value is set to false.
|
||||||
|
|
||||||
value, present = map_var[key]
|
value, present = map_var[key]
|
||||||
|
|
||||||
|
Analogously, receiving a value from a channel can be written as a tuple assignment.
|
||||||
|
|
||||||
value, success = <chan_var
|
value, success = <chan_var
|
||||||
|
|
||||||
|
If the receive operation would block, the boolean is set to false. This provides to avoid
|
||||||
|
blocking on a receive operation.
|
||||||
|
|
||||||
Sending on a channel is a form of assignment. The left hand side expression
|
Sending on a channel is a form of assignment. The left hand side expression
|
||||||
must denote a channel pointer value.
|
must denote a channel pointer value.
|
||||||
|
|
||||||
>chan_ptr = value
|
>chan_ptr = value
|
||||||
|
|
||||||
In assignments, the type of the expression must match the type of the designator.
|
In assignments, the type of the expression must match the type of the designator.
|
||||||
|
|
||||||
|
|
||||||
@ -1136,13 +1156,11 @@ first form of return statement is used:
|
|||||||
|
|
||||||
If statements
|
If statements
|
||||||
|
|
||||||
[ NOTE We propose a simplified control syntax ]
|
|
||||||
|
|
||||||
If statements have the traditional form except that the
|
If statements have the traditional form except that the
|
||||||
condition need not be parenthesized and the statements
|
condition need not be parenthesized and the "then" statement
|
||||||
must be in brace brackets.
|
must be in brace brackets.
|
||||||
|
|
||||||
IfStat = 'if' [ SimpleVarDecl ';' ] Expression Block [ 'else' ( Block | IfStat ) ] .
|
IfStat = 'if' [ SimpleVarDecl ';' ] Expression Block [ 'else' Statement ] .
|
||||||
|
|
||||||
if x > 0 {
|
if x > 0 {
|
||||||
return true;
|
return true;
|
||||||
@ -1165,13 +1183,20 @@ Switch statements
|
|||||||
|
|
||||||
Switches provide multi-way execution.
|
Switches provide multi-way execution.
|
||||||
|
|
||||||
SwitchStat = 'switch' [ SimpleVarDecl ';' ] [ Expression ] '{' CaseList '}' .
|
SwitchStat = 'switch' [ [ SimpleVarDecl ';' ] [ Expression ] ] '{' { CaseClause } '}' .
|
||||||
CaseList = ( 'case' ExpressionList | 'default' ) ':' { Statement | 'fallthrough' ';' } .
|
CaseClause = CaseList { Statement } [ 'fallthrough' ] .
|
||||||
|
CaseList = Case { Case } .
|
||||||
|
Case = ( 'case' ExpressionList | 'default' ) ':' .
|
||||||
|
|
||||||
Note that the expressions do not need to be constants. They will
|
There can be at most one default case in a switch statement.
|
||||||
be evaluated top to bottom until the first successful non-defauit case.
|
|
||||||
If none matches and there is a default case, the default case is
|
The 'fallthrough' keyword indicates that the control should flow from
|
||||||
executed.
|
the end of this case clause to the first statement of the next clause.
|
||||||
|
|
||||||
|
The expressions do not need to be constants. They will
|
||||||
|
be evaluated top to bottom until the first successful non-default case is reached.
|
||||||
|
If none matches and there is a default case, the statements of the default
|
||||||
|
case are executed.
|
||||||
|
|
||||||
switch tag {
|
switch tag {
|
||||||
default: s3()
|
default: s3()
|
||||||
@ -1187,13 +1212,13 @@ the variable is initialized once before the switch is entered.
|
|||||||
case x < 0: return -x
|
case x < 0: return -x
|
||||||
default: return x
|
default: return x
|
||||||
}
|
}
|
||||||
|
|
||||||
Cases do not fall through unless explicitly marked with a 'fallthrough' statement.
|
Cases do not fall through unless explicitly marked with a 'fallthrough' statement.
|
||||||
|
|
||||||
switch a {
|
switch a {
|
||||||
case 1:
|
case 1:
|
||||||
b();
|
b();
|
||||||
fallthrough;
|
fallthrough
|
||||||
case 2:
|
case 2:
|
||||||
c();
|
c();
|
||||||
}
|
}
|
||||||
@ -1207,43 +1232,36 @@ If the expression is omitted, it is equivalent to 'true'.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
While statements
|
|
||||||
|
|
||||||
A while statement is the usual loop construct.
|
|
||||||
|
|
||||||
WhileStat = 'while' [ SimpleVarDecl ';' ] Expression Block .
|
|
||||||
|
|
||||||
while a < b {
|
|
||||||
a++
|
|
||||||
}
|
|
||||||
|
|
||||||
A while statement may include the declaration of a single temporary variable.
|
|
||||||
The scope of the declared variable extends to the end of the while statement, and
|
|
||||||
the variable is initialized once before the loop is entered.
|
|
||||||
|
|
||||||
while x := <ch_ptr; y < x {
|
|
||||||
y++
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
For statements
|
For statements
|
||||||
|
|
||||||
For statements are as in C except the first clause can be a simplified variable
|
For statements are a combination of the 'for' and 'while' loops of C.
|
||||||
declaration.
|
|
||||||
|
|
||||||
ForStat = 'for' [ InitStatement ] ';' [ Condition ] ';' [ Continuation ] Block .
|
ForStat = 'for' [ Condition | ForClause ] Block .
|
||||||
InitStatement = SimpleVarDecl | Expression .
|
ForClause = [ InitStat ] ';' [ Condition ] ';' [ PostStat ] .
|
||||||
|
|
||||||
|
InitStat = SimpleStat .
|
||||||
Condition = Expression .
|
Condition = Expression .
|
||||||
Continuation = Expression | IncDecStatement .
|
PostStat = SimpleStat .
|
||||||
|
|
||||||
|
A SimpleStat is a simple statement such as an assignemnt, a SimpleVarDecl,
|
||||||
|
or an increment or decrement statement. Therefore one may declare a loop
|
||||||
|
variable in the init statement.
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
printf("%d\n", i);
|
printf("%d\n", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
A 'for' statement with just a condition executes until the condition becomes
|
||||||
|
false. Thus it is the same as C 'while' statement.
|
||||||
|
|
||||||
|
for a < b {
|
||||||
|
a *= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
If the condition is absent, it is equivalent to 'true'.
|
If the condition is absent, it is equivalent to 'true'.
|
||||||
|
|
||||||
for ;; {
|
for {
|
||||||
f();
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1261,7 +1279,7 @@ to range over the keys of the map; two identifiers range over the keys and corre
|
|||||||
values. For arrays and strings, the behavior is analogous for integer indices (the keys) and
|
values. For arrays and strings, the behavior is analogous for integer indices (the keys) and
|
||||||
array elements (the values).
|
array elements (the values).
|
||||||
|
|
||||||
a := [ 1, 2, 3];
|
a := [ 1, 2, 3 ];
|
||||||
m := [ "fo" : 2, "foo" : 3, "fooo" : 4 ]
|
m := [ "fo" : 2, "foo" : 3, "fooo" : 4 ]
|
||||||
|
|
||||||
range i := a {
|
range i := a {
|
||||||
@ -1275,19 +1293,29 @@ array elements (the values).
|
|||||||
|
|
||||||
Break statements
|
Break statements
|
||||||
|
|
||||||
Within a for or while loop a break statement terminates execution of the loop.
|
Within a 'for' or 'switch' statement, a 'break' statement terminates execution of
|
||||||
[ TODO Do they work in switches? If not - we avoid an ambiguity ]
|
the innermost 'for' or 'switch' statement.
|
||||||
|
|
||||||
BreakStat = 'break' .
|
BreakStat = 'break' [ identifier ].
|
||||||
|
|
||||||
|
If there is an identifier, it must be the label name of an enclosing 'for' or' 'switch'
|
||||||
|
statement, and that is the one whose execution terminates.
|
||||||
|
|
||||||
|
L: for i < n {
|
||||||
|
switch i {
|
||||||
|
case 5: break L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Continue statements
|
Continue statements
|
||||||
|
|
||||||
Within a for or while loop a continue statement begins the next iteration of the
|
Within a 'for' loop a continue statement begins the next iteration of the
|
||||||
loop. Within a while loop, the continue jumps to the condition; within a for loop
|
loop at the post statement.
|
||||||
it jumps to the continuation statement.
|
|
||||||
|
|
||||||
ContinueStat = 'continue' .
|
ContinueStat = 'continue' [ identifier ].
|
||||||
|
|
||||||
|
The optional identifier is analogous to that of a 'break' statement.
|
||||||
|
|
||||||
|
|
||||||
Goto statements
|
Goto statements
|
||||||
@ -1301,12 +1329,13 @@ GotoStat = 'goto' identifier .
|
|||||||
|
|
||||||
Label statement
|
Label statement
|
||||||
|
|
||||||
A label statement serves as the target of a goto statement.
|
A label statement serves as the target of a 'goto', 'break' or 'continue' statement.
|
||||||
[ TODO This invention is likely to resolve grammatical problems ]
|
|
||||||
|
|
||||||
LabelStat = 'label' identifier ':' .
|
LabelStat = identifier ':' .
|
||||||
|
|
||||||
label Error:
|
Error:
|
||||||
|
|
||||||
|
There are various restrictions [TBD] as to where a label statement can be used.
|
||||||
|
|
||||||
|
|
||||||
Packages
|
Packages
|
||||||
@ -1325,7 +1354,7 @@ A program can access exported items from another package using
|
|||||||
an import declaration:
|
an import declaration:
|
||||||
|
|
||||||
ImportDecl = 'import' [ PackageName ] PackageFileName .
|
ImportDecl = 'import' [ PackageName ] PackageFileName .
|
||||||
PackageFileName = '"' { utf8_char } '"' .
|
PackageFileName = string_lit .
|
||||||
|
|
||||||
|
|
||||||
[ TODO complete this section ]
|
[ TODO complete this section ]
|
||||||
|
Loading…
Reference in New Issue
Block a user