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

For example, the following Gos code:

(func hypot (#(x y float64)) float64

  (return (math.Sqrt (+ (* x x) (* y y)))))

compiles to the Go code:

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

Identifiers are encoded using the following system:

ZA !     ZF &     ZK -     ZP <     ZS ?     ZX |

ZD $     ZH *     ZM /     ZQ =     ZT @     ZY ~

ZE %     ZI +     ZN :     ZR >     ZV ^     ZZ Z

There are plans to encode . as ZL in the future, but not yet. Gos identifiers have the same gamut as Scheme identifiers, and so you can safely use any identifier you would like. They are encoded by the compiler so that they do not collide with Go identifiers and keywords.

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.

The following are type-keywords:

*               chan            interface

map:            chan<-          slice

array           chan<-!         struct

  • (* type) represents pointer types.

  • (map: keytype type) represents map types.

The following are declaration-keywords:

const           import          type

func            package         var

The func keyword is the most polymorphic language construct in Gos.

The following are statement-keywords:

++ -- <-! %= *= += -= /= := <<= >>= =

 

bitwise-and=        goto

bitwise-or=         import

bitwise-xor=        interface

break               package

continue            range

default             return

defer               select

fallthrough         switch

for                 type

go                  var

Expressions may also include Types in Go, so these keywords may also appear in type-expressions. The following are expression-keywords:

!= ! % * & + - / < <- << <= == > >= >>

 

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.

For example:

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

For example:

(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 ')' .

QualifiedIdents may also be written "id.id".

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

Given the declarations

(type

  (Point3D (struct (x y z float64)))

  (Line (struct (p q Point3D))))

one may write

(:= 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 .

For example:

(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 ')'

For example:

(& x)

(& (index a (f 2)))

(* p)

(* (pf x))

5.15  Receive operator

'(<-' Expression ')'

For example:

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

The Statement production is the same as in Go.

6.1  Labeled statements

(label name)

6.2  Expression statements

ExpressionStmt = Expression .

The ExpressionStmt production is the same as in Go.

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 .