108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package parser
|
|
|
|
import "io"
|
|
import "os"
|
|
import "fmt"
|
|
import "github.com/alecthomas/participle/v2"
|
|
import "git.tebibyte.media/sashakoshka/fspl/entity"
|
|
import flexer "git.tebibyte.media/sashakoshka/fspl/lexer"
|
|
|
|
var parser = participle.MustBuild[Tree] (
|
|
participle.Union[entity.TopLevel] (
|
|
new(entity.Function),
|
|
new(entity.Typedef),
|
|
new(entity.Method)),
|
|
participle.Union[entity.Type] (
|
|
new(entity.TypeNamed),
|
|
new(entity.TypePointer),
|
|
new(entity.TypeInterface),
|
|
new(entity.TypeStruct),
|
|
new(entity.TypeArray),
|
|
new(entity.TypeSlice)),
|
|
participle.Union[entity.Expression] (
|
|
new(entity.LiteralInt),
|
|
new(entity.LiteralFloat),
|
|
new(entity.LiteralString),
|
|
new(entity.LiteralArray),
|
|
new(entity.LiteralStruct),
|
|
new(entity.LiteralBoolean),
|
|
new(entity.LiteralNil),
|
|
new(entity.Break),
|
|
new(entity.Return),
|
|
new(entity.IfElse),
|
|
new(entity.Loop),
|
|
new(entity.MethodCall),
|
|
new(entity.MemberAccess),
|
|
new(entity.Declaration),
|
|
new(entity.Subscript),
|
|
new(entity.Slice),
|
|
new(entity.Length),
|
|
new(entity.Dereference),
|
|
new(entity.Reference),
|
|
new(entity.ValueCast),
|
|
new(entity.BitCast),
|
|
new(entity.Operation),
|
|
new(entity.Call),
|
|
new(entity.Variable),
|
|
new(entity.Block)),
|
|
participle.Union[entity.Statement] (
|
|
new(entity.LiteralInt),
|
|
new(entity.LiteralFloat),
|
|
new(entity.LiteralArray),
|
|
new(entity.LiteralStruct),
|
|
new(entity.LiteralBoolean),
|
|
new(entity.LiteralNil),
|
|
new(entity.Break),
|
|
new(entity.Return),
|
|
new(entity.Assignment),
|
|
new(entity.IfElse),
|
|
new(entity.Loop),
|
|
new(entity.MethodCall),
|
|
new(entity.MemberAccess),
|
|
new(entity.Declaration),
|
|
new(entity.Subscript),
|
|
new(entity.Slice),
|
|
new(entity.Length),
|
|
new(entity.Dereference),
|
|
new(entity.Reference),
|
|
new(entity.ValueCast),
|
|
new(entity.BitCast),
|
|
new(entity.Operation),
|
|
new(entity.Call),
|
|
new(entity.Variable),
|
|
new(entity.Block)),
|
|
participle.UseLookahead(participle.MaxLookahead),
|
|
participle.Lexer(flexer.NewDefinition()))
|
|
|
|
// Tree represents a parsed abstract syntax tree. It has no constructor and its
|
|
// zero value can be used safely.
|
|
type Tree struct {
|
|
Declarations []entity.TopLevel `parser:" @@* "`
|
|
}
|
|
|
|
func (this *Tree) String () string {
|
|
out := ""
|
|
for index, declaration := range this.Declarations {
|
|
if index > 0 { out += "\n" }
|
|
out += fmt.Sprint(declaration)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Parse parses the contents of the given io.Reader into the tree.
|
|
func (this *Tree) Parse (name string, file io.Reader) error {
|
|
parsed, err := parser.Parse(name, file)
|
|
if parsed != nil {
|
|
this.Declarations = append(this.Declarations, parsed.Declarations...)
|
|
}
|
|
return err
|
|
}
|
|
|
|
// ParseFile parses the contents of the given file into the tree.
|
|
func (this *Tree) ParseFile (name string) error {
|
|
file, err := os.Open(name)
|
|
if err != nil { return err }
|
|
defer file.Close()
|
|
return this.Parse(name, file)
|
|
}
|