Skip to content

Commit 740dd9b

Browse files
committed
Sloppy initial commit of frenzied dev
0 parents  commit 740dd9b

21 files changed

+4449
-0
lines changed

Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.PHONY: bootstrap build-parser watch
2+
3+
PARSERFILE=lang/parser.go
4+
SAMPLEFILE=samples/sample1.clj
5+
6+
bootstrap:
7+
mkdir -p parser
8+
go get -u github.com/mna/pigeon
9+
go get -u github.com/cespare/reflex
10+
11+
watch:
12+
reflex --inverse-glob=$(PARSERFILE) -- $(MAKE) test-parser
13+
14+
build-parser:
15+
echo "package lang" > $(PARSERFILE)
16+
pigeon <grammar.peg | gofmt >>$(PARSERFILE)
17+
18+
test-parser: build-parser
19+
go run main.go $(SAMPLEFILE)
20+

glide.lock

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package: github.com/davehughes/lparse
2+
import:
3+
- package: github.com/pkg/errors
4+
version: ^0.8.0

grammar.peg

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
{
2+
// Go code goes here...
3+
4+
}
5+
6+
7+
Input <- forms:Form* EOF {
8+
return forms, nil
9+
}
10+
11+
Form <- _ form:( LineComment / List / Lambda / Vector / Set / Map /
12+
QuotedForm / Numeric / Symbol / Keyword / String
13+
) _ {
14+
fmt.Printf("Form: %v\n", form)
15+
return string(c.text), nil
16+
}
17+
18+
EOF = !.
19+
EOL <- LineComment? ( "\r\n" / "\n\r" / "\r" / "\n" / EOF)
20+
_ "whitespace" <- [ \n\t\r,]*
21+
22+
LineComment <- _? ';' comment:[^\r\n]* {
23+
return &Comment{
24+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
25+
Value: fmt.Sprint(comment),
26+
}, nil
27+
/* return showComponent("commented-line", c.text) */
28+
}
29+
30+
List <- '(' forms:Form* ')' {
31+
return &Collection{
32+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
33+
Type: CollectionList,
34+
Items: forms.([]interface{}),
35+
}, nil
36+
}
37+
38+
Vector <- '[' forms:Form* ']' {
39+
return &Collection{
40+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
41+
Type: CollectionVector,
42+
Items: forms.([]interface{}),
43+
}, nil
44+
}
45+
46+
Map <- '{' forms:Form* '}' {
47+
return &Collection{
48+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
49+
Type: CollectionMap,
50+
Items: forms.([]interface{}),
51+
}, nil
52+
}
53+
54+
Set <- '#' '{' forms:Form '}' {
55+
return &Collection{
56+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
57+
Type: CollectionSet,
58+
Items: forms.([]interface{}),
59+
}, nil
60+
}
61+
62+
Lambda <- '#' '(' forms:Form* ')' {
63+
return &Collection{
64+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
65+
Type: CollectionLambda,
66+
Items: forms.([]interface{}),
67+
}, nil
68+
}
69+
70+
Keyword <- ( NamespacedKeyword / BareKeyword)
71+
72+
NamespacedKeyword <- ':' ':' sym:Symbol {
73+
return &Keyword{
74+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
75+
Name: fmt.Sprint(sym),
76+
Namespace: "TODO: namespaced",
77+
}, nil
78+
}
79+
80+
BareKeyword <- ':' sym:Symbol {
81+
return &Keyword{
82+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
83+
Name: fmt.Sprint(sym),
84+
}, nil
85+
}
86+
87+
Symbol <- [a-z0-9-+*?!&^%#?<>%/\\]i+ {
88+
return &Symbol{
89+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
90+
Name: string(c.text),
91+
}, nil
92+
}
93+
94+
QuotedForm <- ( "'" ) form:Form {
95+
return &QuotedForm{
96+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
97+
Form: form,
98+
}, nil
99+
}
100+
101+
String <- '"' value:[^"]* '"' {
102+
return &String{
103+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
104+
Value: string(c.text),
105+
}, nil
106+
}
107+
108+
Numeric <- ( SciNot / Float /Integer )
109+
110+
SciNotSuffix <- [eE] Integer
111+
112+
SciNot <- coefficient:( Float / Integer ) exponent:SciNotSuffix {
113+
fl := fmt.Sprintf("(sci-not %s :exponent %s)", coefficient, exponent)
114+
fmt.Println(fl)
115+
return fl, nil
116+
}
117+
118+
Float <- '-'? [0-9]+ '.' [0-9]+ {
119+
value, err := strconv.ParseFloat(string(c.text), 64)
120+
if err != nil {
121+
panic(err)
122+
}
123+
return &Float{
124+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
125+
ParsedValue: string(c.text),
126+
Value: value,
127+
}, nil
128+
}
129+
130+
Integer <- '-'? [0-9]+ {
131+
value, err := strconv.ParseInt(string(c.text), 0, 64)
132+
if err != nil {
133+
panic(err)
134+
}
135+
return &Integer{
136+
Position: Position{Line: c.pos.line, Column: c.pos.col, Offset: c.pos.offset},
137+
ParsedValue: string(c.text),
138+
Value: value,
139+
}, nil
140+
}

lang/ast.go

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package lang
2+
3+
import "fmt"
4+
5+
func showComponent(t string, c interface{}) (interface{}, error) {
6+
value := fmt.Sprintf("(%s %s)", t, c)
7+
fmt.Println(value)
8+
return value, nil
9+
}
10+
11+
type Keyword struct {
12+
Position
13+
Name string
14+
Namespace string
15+
}
16+
17+
type Symbol struct {
18+
Position
19+
Name string
20+
}
21+
22+
type String struct {
23+
Position
24+
Value string
25+
}
26+
27+
func (s String) String() string {
28+
return fmt.Sprintf("(string %v)", s.Value)
29+
}
30+
31+
type Comment struct {
32+
Position
33+
Value string
34+
}
35+
36+
type Position struct {
37+
Line int
38+
Column int
39+
Offset int
40+
}
41+
42+
type CollectionType int
43+
44+
const (
45+
CollectionList CollectionType = iota
46+
CollectionVector
47+
CollectionMap
48+
CollectionSet
49+
CollectionLambda
50+
)
51+
52+
type Collection struct {
53+
Position
54+
Type CollectionType
55+
Items []interface{}
56+
}
57+
58+
type Integer struct {
59+
Position
60+
ParsedValue string
61+
Value int64
62+
}
63+
64+
type Float struct {
65+
Position
66+
ParsedValue string
67+
Value float64
68+
}
69+
70+
type QuotedForm struct {
71+
Position
72+
Form interface{}
73+
}

lang/eval.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package lang
2+
3+
import "github.com/pkg/errors"
4+
5+
type EvaluationContext struct {
6+
Bindings map[string]interface{}
7+
}
8+
9+
func Eval(form interface{}, ctx *EvaluationContext) (interface{}, error) {
10+
switch t := form.(type) {
11+
case Symbol:
12+
binding, ok := ctx.Bindings[t.Name]
13+
if !ok {
14+
return nil, errors.New("Unbound symbol")
15+
}
16+
return binding, nil
17+
default:
18+
return nil, errors.New("Unrecognized form")
19+
}
20+
}

0 commit comments

Comments
 (0)