Gos Programming Language
1 Introduction
This is a reference manual for the Gos programming language. Gos is an S-expressions syntax for Go, hence the name. Most forms are exactly the same as Go with parentheses added, however there are changes such as map is written map: and if is written when to allow syntactic sugar to be written that matches Scheme more closely.
The purpose of Gos is to write the standard library for Droscheme.
1.1 Examples
|
(func hypot (#(x y float64)) float64 |
|
(return (math.Sqrt (+ (* x x) (* y y))))) |
|
func hypot(x, y float64) float64 { |
|
return math.Sqrt(x*x + y*y) |
|
} |
2 Lexical syntax
Source code is represented as S-expressions similar to Lisp and Scheme.
Almost every language construct is represented with lists, but there is one language construct that is represented with vectors: typed identifiers.
|
#(x y float32) |
|
#(a b c d IdentifierType) |
2.1 Identifiers
|
ZA ! ZF & ZK - ZP < ZS ? ZX | |
|
ZD $ ZH * ZM / ZQ = ZT @ ZY ~ |
|
ZE % ZI + ZN : ZR > ZV ^ ZZ Z |
2.2 Keywords
There are several different kinds of keywords in Gos. All of the keywords in this document are prefixed with go: when run by the compiler system.
|
* chan interface |
|
map: chan<- slice |
|
array chan<-! struct |
(* type) represents pointer types.
(map: keytype type) represents map types.
|
const import type |
|
func package var |
(func param ret ... body?) represents a
function type (FunctionType) in a type context, and a
function literal (FunctionLit) in an expression context.
The param must be a list. (func name param ret ... body?) represents a
method specification (MethodSpec) in an interface context, a
function declaration (FunctionDecl) in an declaration context, and a
function literal assigned to a var (VarDecl) in a statement context.
This is one feature required by all Schemes but is absent in Go; the ability to declare a named function that is local to the scope of the body of a function declaration.
The name must be a symbol.(func receiver name param ret) represents a method declaration (MethodDecl) in a declaration context.
The receiver must be a vector.
|
++ -- <-! %= *= += -= /= := <<= >>= = |
|
|
|
bitwise-and= goto |
|
bitwise-or= import |
|
bitwise-xor= interface |
|
break package |
|
continue range |
|
default return |
|
defer select |
|
fallthrough switch |
|
for type |
|
go var |
|
!= ! % * & + - / < <- << <= == > >= >> |
|
|
|
bitwise-and as |
|
bitwise-or dot |
|
bitwise-xor index |
|
and index-set! |
|
apply or |
|
call xor |
2.3 Integer literals
Integer literals are represented the same as they are in Go.
2.4 Floating-point literals
Floating-point literals are represented the same as they are in Go. Imaginary literals are not supported.
2.5 Character literals
Characters are represented #\char.
2.6 String literals
Strings are represented "string".
3 Types
|
Type = TypeName | TypeLit . |
|
TypeName = QualifiedIdent . |
|
TypeLit = ArrayType |
|
| StructType |
|
| PointerType |
|
| FunctionType |
|
| InterfaceType |
|
| SliceType |
|
| MapType |
|
| ChannelType . |
3.1 Boolean types
The boolean type is written bool and has the values #t and #f.
3.2 Numeric types
Numeric types have the same names as they do in Go.
3.3 String types
The string type is written string.
3.4 Array types
Array types are written (array size type)
|
ArrayType = '(array' ArrayLength ElementType ')' . |
|
ArrayLength = Expression . |
|
ElementType = Type . |
3.5 Slice types
|
SliceType = '(slice' ElementType ')' |
3.6 Struct types
Struct types represent a sequence of fields.
|
StructType = '(struct' { FieldDecl } ')' . |
|
FieldDecl = TypedIdentifierList | Type . |
If a TypedIdentifierList includes no identifiers, then it represents an anonymous field, in which case the Type is restricted to named types and pointers to named types.
|
;An empty struct. |
|
(struct) |
|
|
|
;A struct with 6 fields. |
|
(struct |
|
#(x y int) |
|
#(u float32) |
|
#(_ float32) ; padding |
|
#(A (* (slice int))) |
|
#(F (func () void))) |
3.7 Pointer types
|
PointerType = '(*' Type ')' . |
3.8 Function types
|
FunctionType = '(func' Signature ')'. |
|
Signature = { ParameterDecl } Result . |
|
Result = '(values' { ParameterDecl } ')' | 'void' | Type . |
|
ParameterDecl = TypedIdentifierList | Type . |
One major difference between Go and Gos is that in Go the return type is optional, but in Gos the parameters are optional, and the return type is required.
Ellipses are supported by using the ellipsis keyword, which may be used with array and func.
3.9 Interface types
|
InterfaceType = '(interface' { MethodSpec } ')' . |
|
MethodSpec = '(func' MethodName Signature ')' |
|
| InterfaceTypeName . |
|
MethodName = Identifier . |
|
InterfaceTypeName = TypeName . |
|
(type (Lock (interface |
|
(func Lock void) |
|
(func Unlock void)))) |
3.10 Map types
|
MapType = '(map:' KeyType ElementType ')' . |
|
KeyType = Type . |
3.11 Channel types
|
ChannelType = '(' ChannelKind ElementType ')' . |
|
ChannelKind = 'chan' |
|
| 'chan<-' |
|
| 'chan<-!' . |
4 Declarations
4.1 Constant declarations
|
ConstDecl = '(const' { ConstSpec } ')' . |
|
ConstSpec = '(=' IdentifierList ExpressionList ')' |
|
| '(=' TypedIdentifierList ExpressionList ')' |
|
| Identifier . |
|
|
|
TypedIdentifierList = '#(' { Identifier } Type ')' . |
|
IdentifierList = '(' { Identifier } ')' . |
|
ExpressionList = { Expression } . |
Iota is written iota.
4.2 Type declarations
|
TypeDecl = '(type' { TypeSpec } ')' . |
|
TypeSpec = Identifier Type . |
4.3 Variable declarations
|
VarDecl = '(var { VarSpec } ')' . |
|
VarSpec = '(=' IdentifierList ExpressionList ')' |
|
| '(=' TypedIdentifierList ExpressionList ')' |
|
| TypedIdentifierList . |
4.4 Short variable declarations
|
ShortVarDecl = '(:=' IdentifierList ExpressionList ')' . |
4.5 Function declarations
|
FunctionDecl = '(func' FunctionName Signature Body ')' . |
|
FunctionName = Identifier . |
|
Body = { Statement } . |
4.6 Method declarations
|
MethodDecl = '(func' Receiver MethodName Signature Body ')' . |
|
Receiver = '#(' [ Identifier ] Type ')' . |
Type is restricted to named types or pointers to named types.
5 Expressions
5.1 Operands
|
Operand = Literal | QualifiedIdent | MethodExpr |
|
Literal = BasicLit | CompositeLit | FunctionLit . |
|
BasicLit = int_lit | float_lit | imaginary_lit |
|
| char_lit | string_lit . |
5.2 Qualified identifiers
|
QualifiedIdent = '(dot' { Identifier } Identifier ')' . |
5.3 Composite literals
|
CompositeLit = '(make:' LiteralType LiteralValue ')' |
|
| '(new:' LiteralType LiteralValue ')' . |
|
LiteralType = StructType | ArrayType | SliceType | MapType | TypeName . |
|
LiteralValue = { Element } . |
|
Element = Value | '(:' Key Value ')' . |
|
Key = FieldName | ElementIndex . |
|
FieldName = Identifier . |
|
ElementIndex = Expression . |
|
Value = Expression | CompositeLit . |
The two forms are syntactic sugar for two common composite literal expressions. The make: form represents Type{Values}, and the new: form represents &Type{Values}.
|
(type |
|
(Point3D (struct (x y z float64))) |
|
(Line (struct (p q Point3D)))) |
|
(:= origin (make: Point3D)) ; zero value for Point3D |
|
(:= line (make: Line origin (make: Point3D (: y -4) (: z 12.3)))) |
5.4 Function literals
|
FunctionLit = '(func' Signature Body ')' . |
5.5 Primary expressions
|
PrimaryExpr = Operand |
|
| Conversion |
|
| BuiltinCall |
|
| Selector |
|
| Index |
|
| Slice |
|
| TypeAssertion |
|
| Call . |
5.6 Selectors
|
Selector = '(dot' PrimaryExpr Identifier ')' |
|
| Identifier '.' Identifier . |
5.7 Indexes and Slices
|
IndexSet = '(index-set!' PrimaryExpr Expression Expression ')' . |
|
Index = '(index' PrimaryExpr Expression ')' . |
|
Slice = '(index' PrimaryExpr OptExpr OptExpr ')' . |
|
OptExpr = '#f' | Expression . |
5.8 Type assertions
|
TypeAssertion = '(as' PrimaryExpr Type ')' |
|
| '(as' PrimaryExpr Type Call ')' . |
5.9 Calls
|
BuiltinId = 'new' | 'make' |
|
BuiltinCall = '(' BuiltinId Type { ArgumentList } ')' . |
|
Call = '(' PrimaryExpr { ArgumentList } ')' |
|
| '(call' PrimaryExpr { ArgumentList } ')' |
|
| '(apply' PrimaryExpr { ArgumentList } ')' . |
|
ArgumentList = ExpressionList . |
|
(f a1 a2 … an) |
|
(math.Atan2 x y) |
|
(var #(pt (* Point))) |
|
(pt.Scale 3.5) |
5.10 Operators
|
Expression = PrimaryExpr |
|
| '(' unary_op PrimaryExpr ')' |
|
| '(' binary_op Expression PrimaryExpr ')' . |
|
|
|
binary_op = 'or' | 'and' | rel_op | add_op | mul_op . |
|
rel_op = '==' | '!=' | '<' | '<=' | '>' | '>=' . |
|
add_op = '+' | '-' | 'bitwise-or' | 'bitwise-xor' . |
|
mul_op = '*' | '/' | '%' | '<<' | '>>' |
|
| 'bitwise-and' | 'bitwise-but' . |
|
|
|
unary_op = '+' | '-' | 'not' | 'bitwise-not' |
|
| '*' | '&' | '<-' . |
5.11 Arithmetic operators
Arithmetic operators have the same spellings as they do in Go.
5.12 Comparison operators
Comparison operators have the same spellings as they do in Go.
5.13 Logical operators
Logical operators are spelled differently because of problems with OR.
|
Go Gos (Binary) |
|
& bitwise-and |
|
&= bitwise-and= |
|
&& and |
|
|| or |
|
| bitwise-or |
|
|= bitwise-or= |
|
^ bitwise-xor |
|
^= bitwise-xor= |
|
&^ bitwise-but |
|
&^= bitwise-but= |
|
|
|
Go Gos (Unary) |
|
^ bitwise-not |
|
! not |
5.14 Address operators
|
'(&' Expression ')' |
|
'(*' Expression ')' |
|
(& x) |
|
(& (index a (f 2))) |
|
(* p) |
|
(* (pf x)) |
5.15 Receive operator
|
'(<-' Expression ')' |
|
(= (x ok) (<- ch)) |
|
(:= (x ok) (<- ch)) |
|
(var (= (x ok) (<- ch))) |
5.16 Method expressions
|
MethodExpr = '(dot' ReceiverType MethodName ')' . |
|
ReceiverType = TypeName | '(*' TypeName ')' . |
5.17 Conversions
|
Conversion = '(call' Type Expression ')' . |
6 Statements
|
Statement = Declaration | LabeledStmt | SimpleStmt | GoStmt |
|
| ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
|
| SwitchStmt | SelectStmt | ForStmt | DeferStmt |
|
| FallthroughStmt | Block | IfStmt . |
|
|
|
SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt |
|
| Assignment | ShortVarDecl . |
6.1 Labeled statements
|
(label name) |
6.2 Expression statements
|
ExpressionStmt = Expression . |
6.3 Send statements
|
SendStmt = '(<-!' Channel Expression ')' . |
|
Channel = Expression . |
6.4 IncDec statements
|
(++ x) |
|
(-- x) |
6.5 Assignments
|
Assignment = '(' assign_op '(' ExpressionList ')' ExpressionList ')' . |
|
assign_op = [ add_op | mul_op ] '=' . |
6.6 If statements
|
IfStmt = '(when' Expression Block [ ElseStmt ] ')' |
|
| '(when*' OptStmt Expression Block [ ElseStmt ] ')' |
|
| '(unless' Expression Block [ ElseStmt ] ')' |
|
| '(unless*' OptStmt Expression Block [ ElseStmt ] ')' . |
|
OptStmt = '#f' | SimpleStmt |
|
ElseStmt = '(else' Block ')' . |
|
Block = { Statement } . |
6.7 Switch statements
|
SwitchStmt = ExprSwitchStmt | TypeSwitchStmt . |
|
ExprSwitchStmt = '(cond!' { CondClause } ')' |
|
| '(cond!*' SimpleStmt { CondClause } ')' |
|
| '(case!' Expression { CaseClause } ')' |
|
| '(case!*' SimpleStmt Expression { CaseClause } ')' . |
|
CondClause = '(' Expression Block ')' | '(else' Block ')' . |
|
CaseClause = '((' ExpressionList ')' Block ')' |
|
| '(else' Block ')' . |
|
TypeSwitchStmt = '(type!' TypeGuard { TypeClause } ')' |
|
| '(type!*' SimpleStmt TypeGuard { TypeClause } ')' . |
|
TypeGuard = '(as' PrimaryExpr 'type)' . |
|
| '(:=' Identifier '(as' PrimaryExpr 'type))' . |
|
TypeClause = '((' TypeList ')' Block ')' |
|
| '(else' Block ')' . |
|
TypeList = Type { Type } . |
6.8 For statements
|
ForStmt = '(while' Condition Block ')' |
|
| '(range' RangeClause Block ')' |
|
| '(for' ForClause Block ')' . |
|
|
|
Condition = '#t' | Expression . |
|
ForClause = OptStmt Condition OptStmt . |
|
RangeClause = '(=' IdentifierList Expression ')' |
|
| '(:=' IdentifierList Expression ')' . |
6.9 Go statements
|
GoStmt = '(go' Expression ')' . |
6.10 Select statements
|
SelectStmt = '(comm!' { CommClause } ')' . |
|
CommClause = '(' CommStmt Block ')' |
|
| '(else' Block ')' . |
|
CommStmt = SendStmt | RecvStmt |
|
RecvStmt = '(:=' ExpressionList RecvExpr ')' . |
|
RecvExpr = Expression . |
6.11 Return statements
|
ReturnStmt = '(return' ExpressionList ')' . |
6.12 Break statements
|
BreakStmt = '(break' [ Label ] ')' . |
6.13 Continue statements
|
ContinueStmt = '(continue' [ Label ] ')' . |
6.14 Goto statements
|
GotoStmt = '(goto' Label ')' . |
6.15 Fallthrough statements
|
FallthroughStmt = '(fallthrough)' . |
6.16 Defer statements
|
DeferStmt = '(defer' Expression ')' . |
7 Packages
|
SourceFile = '(' PackageClause { ImportDecl } { TopLevelDecl } ')' . |
7.1 Package clause
|
PackageClause = 'package' PackageName . |
|
PackageName = Identifier . |
7.2 Import declarations
|
ImportDecl = '(import' { ImportSpec } ')' . |
|
ImportSpec = '(as' PackageName ImportPath ')' |
|
| '(dot' ImportPath ')' |
|
| ImportPath . |
|
ImportPath = string_lit . |