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 . |