Tested and fixed a lot of expressions
This commit is contained in:
parent
40514cfcf9
commit
701bf13a3a
@ -105,7 +105,7 @@ func (this *Reference) String () string {
|
|||||||
// interface. A value cast is never a valid location expression.
|
// interface. A value cast is never a valid location expression.
|
||||||
type ValueCast struct {
|
type ValueCast struct {
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Type Expression `parser:" '[' 'cast' @@ "`
|
Type Type `parser:" '[' 'cast' @@ "`
|
||||||
Value Expression `parser:" @@ ']' "`
|
Value Expression `parser:" @@ ']' "`
|
||||||
}
|
}
|
||||||
func (*ValueCast) expression(){}
|
func (*ValueCast) expression(){}
|
||||||
@ -119,7 +119,7 @@ func (this *ValueCast) String () string {
|
|||||||
// location expression.
|
// location expression.
|
||||||
type BitCast struct {
|
type BitCast struct {
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Type Expression `parser:" '[' 'bitcast' @@ "`
|
Type Type `parser:" '[' 'bitcast' @@ "`
|
||||||
Value Expression `parser:" @@ ']' "`
|
Value Expression `parser:" @@ ']' "`
|
||||||
}
|
}
|
||||||
func (*BitCast) expression(){}
|
func (*BitCast) expression(){}
|
||||||
@ -133,12 +133,13 @@ func (this *BitCast) String () string {
|
|||||||
// be assigned to interfaces. An operation is never a valid location expression.
|
// be assigned to interfaces. An operation is never a valid location expression.
|
||||||
type Operation struct {
|
type Operation struct {
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Operator string `parser:" '[' @('+' | '++' | '-' | '--' | '*' | '/' | '%' | '!!' | '||' | '&&' | '^^' | '!' | '|' | '&' | '^' | '<<' | '>>' | '<' | '>' | '<=' | '>=' | '=') "`
|
// FIXME super janky, need to make a custom lexer at some point
|
||||||
|
Operator Operator `parser:" '[' @('+''+' | '+' | '-''-' | '-' | '*' | '/' | '%' | '!''!' | '|''|' | '&''&' | '^''^' | '!' | '|' | '&' | '^' | '<''<' | '>''>' | '<' | '>' | '<''=' | '>''=' | '=') "`
|
||||||
Arguments []Expression `parser:" @@+ ']' "`
|
Arguments []Expression `parser:" @@+ ']' "`
|
||||||
}
|
}
|
||||||
func (*Operation) expression(){}
|
func (*Operation) expression(){}
|
||||||
func (this *Operation) String () string {
|
func (this *Operation) String () string {
|
||||||
out := "[" + this.Operator
|
out := fmt.Sprint("[", this.Operator)
|
||||||
for _, argument := range this.Arguments {
|
for _, argument := range this.Arguments {
|
||||||
out += fmt.Sprint(" ", argument)
|
out += fmt.Sprint(" ", argument)
|
||||||
}
|
}
|
||||||
@ -157,8 +158,9 @@ type Block struct {
|
|||||||
func (*Block) expression(){}
|
func (*Block) expression(){}
|
||||||
func (this *Block) String () string {
|
func (this *Block) String () string {
|
||||||
out := "{"
|
out := "{"
|
||||||
for _, step := range this.Steps {
|
for index, step := range this.Steps {
|
||||||
out += fmt.Sprint(" ", step)
|
if index > 0 { out += " " }
|
||||||
|
out += fmt.Sprint(step)
|
||||||
}
|
}
|
||||||
return out + "}"
|
return out + "}"
|
||||||
}
|
}
|
||||||
@ -171,7 +173,7 @@ func (this *Block) String () string {
|
|||||||
// struct being accessed is.
|
// struct being accessed is.
|
||||||
type MemberAccess struct {
|
type MemberAccess struct {
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Source Expression `parser:" @@ "`
|
Source *Variable `parser:" @@ "`
|
||||||
Member string `parser:" '.' @Ident "`
|
Member string `parser:" '.' @Ident "`
|
||||||
}
|
}
|
||||||
func (*MemberAccess) expression(){}
|
func (*MemberAccess) expression(){}
|
||||||
@ -184,8 +186,8 @@ func (this *MemberAccess) String () string {
|
|||||||
// method access is never a valid location expression.
|
// method access is never a valid location expression.
|
||||||
type MethodAccess struct {
|
type MethodAccess struct {
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Source Expression `parser:" @@ "`
|
Source *Variable `parser:" @@ "`
|
||||||
Member string `parser:" '::' @Ident "`
|
Member string `parser:" ':' ':' @Ident "`
|
||||||
}
|
}
|
||||||
func (*MethodAccess) expression(){}
|
func (*MethodAccess) expression(){}
|
||||||
func (this *MethodAccess) String () string {
|
func (this *MethodAccess) String () string {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
import "strings"
|
||||||
import "github.com/alecthomas/participle/v2/lexer"
|
import "github.com/alecthomas/participle/v2/lexer"
|
||||||
|
|
||||||
// Signature is a function or method signature that is used in functions,
|
// Signature is a function or method signature that is used in functions,
|
||||||
@ -35,3 +36,86 @@ type Member struct {
|
|||||||
func (this *Member) String () string {
|
func (this *Member) String () string {
|
||||||
return fmt.Sprint(this.Name, ":", this.Value)
|
return fmt.Sprint(this.Name, ":", this.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Operator determines which operation to apply to a value in an operation
|
||||||
|
// expression.
|
||||||
|
type Operator int; const (
|
||||||
|
// Math
|
||||||
|
OperatorAdd Operator = iota
|
||||||
|
OperatorIncrement
|
||||||
|
OperatorSubtract
|
||||||
|
OperatorDecrement
|
||||||
|
OperatorMultiply
|
||||||
|
OperatorDivide
|
||||||
|
OperatorModulo
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
OperatorLogicalNot
|
||||||
|
OperatorLogicalOr
|
||||||
|
OperatorLogicalAnd
|
||||||
|
OperatorLogicalXor
|
||||||
|
|
||||||
|
// Bit manipulation
|
||||||
|
OperatorNot
|
||||||
|
OperatorOr
|
||||||
|
OperatorAnd
|
||||||
|
OperatorXor
|
||||||
|
OperatorLeftShift
|
||||||
|
OperatorRightShift
|
||||||
|
|
||||||
|
// Comparison
|
||||||
|
OperatorLess
|
||||||
|
OperatorGreater
|
||||||
|
OperatorLessEqual
|
||||||
|
OperatorGreaterEqual
|
||||||
|
OperatorEqual
|
||||||
|
)
|
||||||
|
|
||||||
|
var operatorToString = []string {
|
||||||
|
// Math
|
||||||
|
"+",
|
||||||
|
"++",
|
||||||
|
"-",
|
||||||
|
"--",
|
||||||
|
"*",
|
||||||
|
"/",
|
||||||
|
"%",
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
"!",
|
||||||
|
"|",
|
||||||
|
"&",
|
||||||
|
"^",
|
||||||
|
// Bit manipulation
|
||||||
|
"!!",
|
||||||
|
"||",
|
||||||
|
"&&",
|
||||||
|
"^^",
|
||||||
|
"<<",
|
||||||
|
">>",
|
||||||
|
|
||||||
|
// Comparison
|
||||||
|
"<",
|
||||||
|
">",
|
||||||
|
"<=",
|
||||||
|
">=",
|
||||||
|
"=",
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringToOperator map[string] Operator
|
||||||
|
|
||||||
|
func init () {
|
||||||
|
stringToOperator = make(map[string] Operator)
|
||||||
|
for index, str := range operatorToString {
|
||||||
|
stringToOperator[str] = Operator(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Operator) Capture (str []string) error {
|
||||||
|
*this = stringToOperator[strings.Join(str, "")]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this Operator) String () string {
|
||||||
|
return operatorToString[this]
|
||||||
|
}
|
||||||
|
@ -4,11 +4,13 @@ import "testing"
|
|||||||
|
|
||||||
func TestType (test *testing.T) {
|
func TestType (test *testing.T) {
|
||||||
testString (test,
|
testString (test,
|
||||||
|
// correct
|
||||||
`BasicInt: Int
|
`BasicInt: Int
|
||||||
Structure: (x:Int y:Int)
|
Structure: (x:Int y:Int)
|
||||||
Interface: ([aMethod x:Int]:*U8 [otherMethod arg:5:Int]:*U8)
|
Interface: ([aMethod x:Int]:*U8 [otherMethod arg:5:Int]:*U8)
|
||||||
Array: 16:16:16:Int`,
|
Array: 16:16:16:Int
|
||||||
|
StructArray: 31:24:340920:(x:Int y:Int)`,
|
||||||
|
// input
|
||||||
`
|
`
|
||||||
BasicInt: Int
|
BasicInt: Int
|
||||||
Structure: (
|
Structure: (
|
||||||
@ -17,5 +19,58 @@ Structure: (
|
|||||||
Interface: (
|
Interface: (
|
||||||
[aMethod x:Int]:*U8
|
[aMethod x:Int]:*U8
|
||||||
[otherMethod arg:5:Int]:*U8)
|
[otherMethod arg:5:Int]:*U8)
|
||||||
Array: 16:16:16:Int`)
|
Array: 16:16:16:Int
|
||||||
|
StructArray: 31:24:340920:(
|
||||||
|
x:Int
|
||||||
|
y:Int)
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExpression (test *testing.T) {
|
||||||
|
testString (test,
|
||||||
|
// correct
|
||||||
|
`[int]:Int = 5
|
||||||
|
[var] = sdfdf
|
||||||
|
[memberAccess] = sdfdf.a
|
||||||
|
[methodAccess] = sdfdf::method
|
||||||
|
[declaration] = sdfdf:Int
|
||||||
|
[call] = [print 3 1]
|
||||||
|
[emptyBlock] = {}
|
||||||
|
[nestedBlock] = {342 93.34 {3948 32}}
|
||||||
|
[subscript] = [.arr 3]
|
||||||
|
[dereference] = [.ptr]
|
||||||
|
[reference] = [@val]
|
||||||
|
[valueCast] = [cast F32 someValue]
|
||||||
|
[bitCast] = [bitcast 4:U8 someValue]
|
||||||
|
[math] = {[+ 3 4 2 [/ 24 3]] [|| 3 [<< 56 4]] [++ 3] [-- 3] [- 3 1]}`,
|
||||||
|
// input
|
||||||
|
`
|
||||||
|
[int]:Int = 5
|
||||||
|
[var] = sdfdf
|
||||||
|
[memberAccess] = sdfdf.a
|
||||||
|
[methodAccess] = sdfdf::method
|
||||||
|
[declaration] = sdfdf:Int
|
||||||
|
[call] = [print 3 1]
|
||||||
|
[emptyBlock] = { }
|
||||||
|
[nestedBlock] = {
|
||||||
|
342
|
||||||
|
93.34
|
||||||
|
{
|
||||||
|
3948
|
||||||
|
32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[subscript] = [. arr 3]
|
||||||
|
[dereference] = [. ptr]
|
||||||
|
[reference] = [@ val]
|
||||||
|
[valueCast] = [cast F32 someValue]
|
||||||
|
[bitCast] = [bitcast 4:U8 someValue]
|
||||||
|
[math] = {
|
||||||
|
[+ 3 4 2 [/ 24 3]]
|
||||||
|
[|| 3 [<< 56 4]]
|
||||||
|
[++ 3]
|
||||||
|
[-- 3]
|
||||||
|
[- 3 1]
|
||||||
|
}
|
||||||
|
`)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ type Function struct {
|
|||||||
// Syntax
|
// Syntax
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Public bool `parser:" @'+'? "`
|
Public bool `parser:" @'+'? "`
|
||||||
Signature `parser:" @@ "`
|
Signature *Signature `parser:" @@ "`
|
||||||
Body Expression `parser:" ( '=' @@ )? "`
|
Body Expression `parser:" ( '=' @@ )? "`
|
||||||
}
|
}
|
||||||
func (*Function) topLevel(){}
|
func (*Function) topLevel(){}
|
||||||
@ -60,7 +60,7 @@ type Method struct {
|
|||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Public bool `parser:" @'+'? "`
|
Public bool `parser:" @'+'? "`
|
||||||
TypeName string `parser:" @Ident "`
|
TypeName string `parser:" @Ident "`
|
||||||
Signature `parser:" '.' @@ "`
|
Signature *Signature `parser:" '.' @@ "`
|
||||||
Body Expression `parser:" ( '=' @@ )? "`
|
Body Expression `parser:" ( '=' @@ )? "`
|
||||||
}
|
}
|
||||||
func (*Method) topLevel(){}
|
func (*Method) topLevel(){}
|
||||||
|
@ -4,6 +4,7 @@ import "io"
|
|||||||
import "os"
|
import "os"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "github.com/alecthomas/participle/v2"
|
import "github.com/alecthomas/participle/v2"
|
||||||
|
import "github.com/alecthomas/participle/v2/lexer"
|
||||||
|
|
||||||
var parser = participle.MustBuild[Tree] (
|
var parser = participle.MustBuild[Tree] (
|
||||||
participle.Union[TopLevel] (
|
participle.Union[TopLevel] (
|
||||||
@ -21,24 +22,37 @@ var parser = participle.MustBuild[Tree] (
|
|||||||
&LiteralFloat { },
|
&LiteralFloat { },
|
||||||
&LiteralArray { },
|
&LiteralArray { },
|
||||||
&LiteralStruct { },
|
&LiteralStruct { },
|
||||||
&Variable { },
|
&MemberAccess { },
|
||||||
&Declaration { },
|
&Declaration { },
|
||||||
&Call { },
|
&MethodAccess { },
|
||||||
|
&Variable { },
|
||||||
&Subscript { },
|
&Subscript { },
|
||||||
&Dereference { },
|
&Dereference { },
|
||||||
&Reference { },
|
&Reference { },
|
||||||
&ValueCast { },
|
&ValueCast { },
|
||||||
&BitCast { },
|
&BitCast { },
|
||||||
&Operation { },
|
&Operation { },
|
||||||
|
&Call { },
|
||||||
&Block { },
|
&Block { },
|
||||||
&MemberAccess { },
|
|
||||||
&MethodAccess { },
|
|
||||||
&IfElse { },
|
&IfElse { },
|
||||||
&Loop { },
|
// &Loop { },
|
||||||
&Break { },
|
// &Break { },
|
||||||
&Return { },
|
// &Return { },
|
||||||
&Assignment { }),
|
// &Assignment { },
|
||||||
participle.UseLookahead(participle.MaxLookahead))
|
),
|
||||||
|
participle.UseLookahead(participle.MaxLookahead),
|
||||||
|
// participle.Lexer(basicLexer),
|
||||||
|
)
|
||||||
|
|
||||||
|
var basicLexer = lexer.MustSimple([]lexer.SimpleRule {
|
||||||
|
{ Name: "Comment", Pattern: `\/\/.*`},
|
||||||
|
{ Name: "String", Pattern: `"(\\"|[^"])*"`},
|
||||||
|
{ Name: "Int", Pattern: `[-+]?\d+`},
|
||||||
|
{ Name: "Float", Pattern: `[-+]?(\d*\.)?\d+`},
|
||||||
|
{ Name: "Ident", Pattern: `[a-zA-Z_]\w*`},
|
||||||
|
{ Name: "Bracket", Pattern: `[[\]{}()]`},
|
||||||
|
{ Name: "whitespace", Pattern: `[ \t\n\r]+`},
|
||||||
|
})
|
||||||
|
|
||||||
// Tree represents a parsed abstract syntax tree. It has no constructor and its
|
// Tree represents a parsed abstract syntax tree. It has no constructor and its
|
||||||
// zero value can be used safely.
|
// zero value can be used safely.
|
||||||
|
Loading…
Reference in New Issue
Block a user