Skip to content

Commit e7ab963

Browse files
committed
Initial commit
0 parents  commit e7ab963

File tree

19 files changed

+3400
-0
lines changed

19 files changed

+3400
-0
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# WebAssembly Interface Definition Language (WIDL) for Golang
2+
3+
WIDL is a schema format for describing [waPC](https://github.com/wapc) modules and used by the [CLI](https://github.com/wapc/cli) to generate code for the supported guest languages. It heavily resembles [GraphQL schema](https://graphql.org/learn/schema/) but with some variations to fit better in the WebAssembly ecosystem.
4+
5+
* Built-in WebAssembly numeric types (i8-64, i8-64, f32, f64) - no scalars required
6+
* Scalars explicitly alias a known type
7+
* Functions can return `void` instead of returning `Boolean` as a workaround
8+
* Fields are required by default instead of optional and `?` is used after the field name to denote that it is optional
9+
* Support for maps
10+
* Operations are defined in a single interface instead of separating query and mutation operations
11+
* Removed the concepts that do not apply from GraphQL schema (e.g. Queries vs. Mutations, Field arguments, Variables, Fragments)
12+
13+
Everything in this package was borrowed and retrofitted from the awesome [Golang GraphQL library](https://github.com/graphql-go/graphql). We thank the 70+ contributors to this project! It has enabled us to provide a succinct interface definition language to our users with minimal effort.

errors/error.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package errors
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
7+
"github.com/wapc/widl-go/language/ast"
8+
"github.com/wapc/widl-go/language/location"
9+
"github.com/wapc/widl-go/language/source"
10+
)
11+
12+
type Error struct {
13+
Message string
14+
Stack string
15+
Nodes []ast.Node
16+
Source *source.Source
17+
Positions []int
18+
Locations []location.SourceLocation
19+
OriginalError error
20+
Path []interface{}
21+
}
22+
23+
// implements Golang's built-in `error` interface
24+
func (g Error) Error() string {
25+
return fmt.Sprintf("%v", g.Message)
26+
}
27+
28+
func NewError(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, origError error) *Error {
29+
return newError(message, nodes, stack, source, positions, nil, origError)
30+
}
31+
32+
func NewErrorWithPath(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, path []interface{}, origError error) *Error {
33+
return newError(message, nodes, stack, source, positions, path, origError)
34+
}
35+
36+
func newError(message string, nodes []ast.Node, stack string, source *source.Source, positions []int, path []interface{}, origError error) *Error {
37+
if stack == "" && message != "" {
38+
stack = message
39+
}
40+
if source == nil {
41+
for _, node := range nodes {
42+
// get source from first node
43+
if node == nil || reflect.ValueOf(node).IsNil() {
44+
continue
45+
}
46+
if node.GetLoc() != nil {
47+
source = node.GetLoc().Source
48+
}
49+
break
50+
}
51+
}
52+
if len(positions) == 0 && len(nodes) > 0 {
53+
for _, node := range nodes {
54+
if node == nil || reflect.ValueOf(node).IsNil() {
55+
continue
56+
}
57+
if node.GetLoc() == nil {
58+
continue
59+
}
60+
positions = append(positions, node.GetLoc().Start)
61+
}
62+
}
63+
locations := []location.SourceLocation{}
64+
for _, pos := range positions {
65+
loc := location.GetLocation(source, pos)
66+
locations = append(locations, loc)
67+
}
68+
return &Error{
69+
Message: message,
70+
Stack: stack,
71+
Nodes: nodes,
72+
Source: source,
73+
Positions: positions,
74+
Locations: locations,
75+
OriginalError: origError,
76+
Path: path,
77+
}
78+
}

errors/syntax.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package errors
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/wapc/widl-go/language/ast"
9+
"github.com/wapc/widl-go/language/location"
10+
"github.com/wapc/widl-go/language/source"
11+
)
12+
13+
func NewSyntaxError(s *source.Source, position int, description string) *Error {
14+
l := location.GetLocation(s, position)
15+
return NewError(
16+
fmt.Sprintf("Syntax Error %s (%d:%d) %s\n\n%s", s.Name, l.Line, l.Column, description, highlightSourceAtLocation(s, l)),
17+
[]ast.Node{},
18+
"",
19+
s,
20+
[]int{position},
21+
nil,
22+
)
23+
}
24+
25+
// printCharCode here is slightly different from lexer.printCharCode()
26+
func printCharCode(code rune) string {
27+
// print as ASCII for printable range
28+
if code >= 0x0020 {
29+
return fmt.Sprintf(`%c`, code)
30+
}
31+
// Otherwise print the escaped form. e.g. `"\\u0007"`
32+
return fmt.Sprintf(`\u%04X`, code)
33+
}
34+
func printLine(str string) string {
35+
strSlice := []string{}
36+
for _, runeValue := range str {
37+
strSlice = append(strSlice, printCharCode(runeValue))
38+
}
39+
return fmt.Sprintf(`%s`, strings.Join(strSlice, ""))
40+
}
41+
func highlightSourceAtLocation(s *source.Source, l location.SourceLocation) string {
42+
line := l.Line
43+
prevLineNum := fmt.Sprintf("%d", (line - 1))
44+
lineNum := fmt.Sprintf("%d", line)
45+
nextLineNum := fmt.Sprintf("%d", (line + 1))
46+
padLen := len(nextLineNum)
47+
lines := regexp.MustCompile("\r\n|[\n\r]").Split(string(s.Body), -1)
48+
var highlight string
49+
if line >= 2 {
50+
highlight += fmt.Sprintf("%s: %s\n", lpad(padLen, prevLineNum), printLine(lines[line-2]))
51+
}
52+
highlight += fmt.Sprintf("%s: %s\n", lpad(padLen, lineNum), printLine(lines[line-1]))
53+
for i := 1; i < (2 + padLen + l.Column); i++ {
54+
highlight += " "
55+
}
56+
highlight += "^\n"
57+
if line < len(lines) {
58+
highlight += fmt.Sprintf("%s: %s\n", lpad(padLen, nextLineNum), printLine(lines[line]))
59+
}
60+
return highlight
61+
}
62+
63+
func lpad(l int, s string) string {
64+
var r string
65+
for i := 1; i < (l - len(s) + 1); i++ {
66+
r += " "
67+
}
68+
return r + s
69+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/wapc/widl-go
2+
3+
go 1.15

language/ast/annotations.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package ast
2+
3+
import (
4+
"github.com/wapc/widl-go/language/kinds"
5+
)
6+
7+
// Annotation implements Node
8+
type Annotation struct {
9+
Kind string
10+
Loc *Location
11+
Name *Name
12+
Arguments []*Argument
13+
}
14+
15+
func NewAnnotation(an *Annotation) *Annotation {
16+
if an == nil {
17+
an = &Annotation{}
18+
}
19+
return &Annotation{
20+
Kind: kinds.Annotation,
21+
Loc: an.Loc,
22+
Name: an.Name,
23+
Arguments: an.Arguments,
24+
}
25+
}
26+
27+
func (an *Annotation) GetKind() string {
28+
return an.Kind
29+
}
30+
31+
func (an *Annotation) GetLoc() *Location {
32+
return an.Loc
33+
}

language/ast/arguments.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package ast
2+
3+
import (
4+
"github.com/wapc/widl-go/language/kinds"
5+
)
6+
7+
// Argument implements Node
8+
type Argument struct {
9+
Kind string
10+
Loc *Location
11+
Name *Name
12+
Value Value
13+
}
14+
15+
func NewArgument(arg *Argument) *Argument {
16+
if arg == nil {
17+
arg = &Argument{}
18+
}
19+
arg.Kind = kinds.Argument
20+
return arg
21+
}
22+
23+
func (arg *Argument) GetKind() string {
24+
return arg.Kind
25+
}
26+
27+
func (arg *Argument) GetLoc() *Location {
28+
return arg.Loc
29+
}

language/ast/definitions.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package ast
2+
3+
import (
4+
"github.com/wapc/widl-go/language/kinds"
5+
)
6+
7+
type Definition interface {
8+
GetKind() string
9+
GetLoc() *Location
10+
}
11+
12+
// Ensure that all definition types implements Definition interface
13+
var _ Definition = (TypeSystemDefinition)(nil) // experimental non-spec addition.
14+
15+
// AnnotationDefinition implements Node, Definition
16+
type AnnotationDefinition struct {
17+
Kind string
18+
Loc *Location
19+
Name *Name
20+
Description *StringValue
21+
Arguments []*InputValueDefinition
22+
Locations []*Name
23+
}
24+
25+
func NewAnnotationDefinition(def *AnnotationDefinition) *AnnotationDefinition {
26+
if def == nil {
27+
def = &AnnotationDefinition{}
28+
}
29+
return &AnnotationDefinition{
30+
Kind: kinds.AnnotationDefinition,
31+
Loc: def.Loc,
32+
Name: def.Name,
33+
Description: def.Description,
34+
Arguments: def.Arguments,
35+
Locations: def.Locations,
36+
}
37+
}
38+
39+
func (def *AnnotationDefinition) GetKind() string {
40+
return def.Kind
41+
}
42+
43+
func (def *AnnotationDefinition) GetLoc() *Location {
44+
return def.Loc
45+
}
46+
47+
func (def *AnnotationDefinition) GetDescription() *StringValue {
48+
return def.Description
49+
}

language/ast/document.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package ast
2+
3+
import (
4+
"github.com/wapc/widl-go/language/kinds"
5+
)
6+
7+
// Document implements Node
8+
type Document struct {
9+
Kind string
10+
Loc *Location
11+
Definitions []Node
12+
}
13+
14+
func NewDocument(d *Document) *Document {
15+
if d == nil {
16+
d = &Document{}
17+
}
18+
return &Document{
19+
Kind: kinds.Document,
20+
Loc: d.Loc,
21+
Definitions: d.Definitions,
22+
}
23+
}
24+
25+
func (node *Document) GetKind() string {
26+
return node.Kind
27+
}
28+
29+
func (node *Document) GetLoc() *Location {
30+
return node.Loc
31+
}

language/ast/location.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package ast
2+
3+
import (
4+
"github.com/wapc/widl-go/language/source"
5+
)
6+
7+
type Location struct {
8+
Start int
9+
End int
10+
Source *source.Source
11+
}
12+
13+
func NewLocation(loc *Location) *Location {
14+
if loc == nil {
15+
loc = &Location{}
16+
}
17+
return &Location{
18+
Start: loc.Start,
19+
End: loc.End,
20+
Source: loc.Source,
21+
}
22+
}

language/ast/name.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ast
2+
3+
import (
4+
"github.com/wapc/widl-go/language/kinds"
5+
)
6+
7+
// Name implements Node
8+
type Name struct {
9+
Kind string
10+
Loc *Location
11+
Value string
12+
}
13+
14+
func NewName(node *Name) *Name {
15+
if node == nil {
16+
node = &Name{}
17+
}
18+
node.Kind = kinds.Name
19+
return node
20+
}
21+
22+
func (node *Name) GetKind() string {
23+
return node.Kind
24+
}
25+
26+
func (node *Name) GetLoc() *Location {
27+
return node.Loc
28+
}

0 commit comments

Comments
 (0)