File: ast.go

package info (click to toggle)
golang-github-alecthomas-participle-v2 2.1.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 920 kB
  • sloc: javascript: 1,164; sh: 41; makefile: 7
file content (154 lines) | stat: -rw-r--r-- 2,372 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// nolint: golint
package main

import (
	"io"
	"strings"

	"github.com/alecthomas/participle/v2/lexer"
)

// Parse a BASIC program.
func Parse(r io.Reader) (*Program, error) {
	program, err := basicParser.Parse("", r)
	if err != nil {
		return nil, err
	}
	program.init()
	return program, nil
}

type Program struct {
	Pos lexer.Position

	Commands []*Command `@@*`

	Table map[int]*Command
}

type Command struct {
	Pos lexer.Position

	Index int

	Line int `@Number`

	Remark *Remark `(   @@`
	Input  *Input  `  | @@`
	Let    *Let    `  | @@`
	Goto   *Goto   `  | @@`
	If     *If     `  | @@`
	Print  *Print  `  | @@`
	Call   *Call   `  | @@ ) EOL`
}

type Remark struct {
	Pos lexer.Position

	Comment string `@Comment`
}

type Call struct {
	Pos lexer.Position

	Name string        `@Ident`
	Args []*Expression `"(" ( @@ ( "," @@ )* )? ")"`
}

type Print struct {
	Pos lexer.Position

	Expression *Expression `"PRINT" @@`
}

type Input struct {
	Pos lexer.Position

	Variable string `"INPUT" @Ident`
}

type Let struct {
	Pos lexer.Position

	Variable string      `"LET" @Ident`
	Value    *Expression `"=" @@`
}

type Goto struct {
	Pos lexer.Position

	Line int `"GOTO" @Number`
}

type If struct {
	Pos lexer.Position

	Condition *Expression `"IF" @@`
	Line      int         `"THEN" @Number`
}

type Operator string

func (o *Operator) Capture(s []string) error {
	*o = Operator(strings.Join(s, ""))
	return nil
}

type Value struct {
	Pos lexer.Position

	Number        *float64    `  @Number`
	Variable      *string     `| @Ident`
	String        *string     `| @String`
	Call          *Call       `| @@`
	Subexpression *Expression `| "(" @@ ")"`
}

type Factor struct {
	Pos lexer.Position

	Base     *Value `@@`
	Exponent *Value `( "^" @@ )?`
}

type OpFactor struct {
	Pos lexer.Position

	Operator Operator `@("*" | "/")`
	Factor   *Factor  `@@`
}

type Term struct {
	Pos lexer.Position

	Left  *Factor     `@@`
	Right []*OpFactor `@@*`
}

type OpTerm struct {
	Pos lexer.Position

	Operator Operator `@("+" | "-")`
	Term     *Term    `@@`
}

type Cmp struct {
	Pos lexer.Position

	Left  *Term     `@@`
	Right []*OpTerm `@@*`
}

type OpCmp struct {
	Pos lexer.Position

	Operator Operator `@("=" | "<" "=" | ">" "=" | "<" | ">" | "!" "=")`
	Cmp      *Cmp     `@@`
}

type Expression struct {
	Pos lexer.Position

	Left  *Cmp     `@@`
	Right []*OpCmp `@@*`
}