New syntax for method calls

This will free up the '::' token for namespace/module access. Exciting!
This commit is contained in:
Sasha Koshka 2023-10-19 17:19:23 -04:00
parent 30636e18aa
commit 75c18763a9
4 changed files with 68 additions and 53 deletions

View File

@ -19,8 +19,12 @@ type Statement interface {
// it may be directly assigned to an interface. A variable is always a valid
// location expression.
type Variable struct {
// Syntax
Pos lexer.Position
Name string `parser:" @Ident "`
// Semantics
Declaration *Declaration
}
func (*Variable) expression(){}
func (*Variable) statement(){}
@ -44,21 +48,43 @@ func (this *Declaration) String () string {
return fmt.Sprint(this.Name, ":", this.Type)
}
// Call calls upon the function specified by the first argument, and passes the
// rest of that argument to the function. The first argument must be a function
// type, usually the name of a function. The result of a call may be assigned to
// any type matching the function's return type. Since it contains inherent type
// information, it may be directly assigned to an interface. A call is never a
// valid location expression.
// Call calls upon the function specified by the first argument, passing the
// rest of the arguments to that function. The first argument must be a function
// name. The result of a call may be assigned to any type matching the
// function's return type. Since it contains inherent type information, it may
// be directly assigned to an interface. A call is never a valid location
// expression.
type Call struct {
Pos lexer.Position
Function Expression `parser:" '[' @@ "`
Name string `parser:" '[' @Ident "`
Arguments []Expression `parser:" @@* ']' "`
}
func (*Call) expression(){}
func (*Call) statement(){}
func (this *Call) String () string {
out := fmt.Sprint("[", this.Function)
out := fmt.Sprint("[", this.Name)
for _, argument := range this.Arguments {
out += fmt.Sprint(" ", argument)
}
return out + "]"
}
// MethodCall calls upon the method of the variable before the dot that is
// specified by the first argument, passing the rest of the arguments to the
// method. The first argument must be a method name. The result of a call may be
// assigned to any type matching the method's return type. Since it contains
// inherent type information, it may be directly assigned to an interface.
// A method call is never a valid location expression.
type MethodCall struct {
Pos lexer.Position
Source *Variable `parser:" @@ '.' "`
Name string `parser:" '[' @Ident "`
Arguments []Expression `parser:" @@* ']' "`
}
func (*MethodCall) expression(){}
func (*MethodCall) statement(){}
func (this *MethodCall) String () string {
out := fmt.Sprint(this.Source, ".[", this.Name)
for _, argument := range this.Arguments {
out += fmt.Sprint(" ", argument)
}
@ -226,20 +252,6 @@ func (this *MemberAccess) String () string {
return fmt.Sprint(this.Source, ".", this.Member)
}
// Method access allows referring to a specific method of a type, or a behavior
// of an interface. It can only be assigned to the first argument of a call. A
// method access is never a valid location expression.
type MethodAccess struct {
Pos lexer.Position
Source *Variable `parser:" @@ "`
Member string `parser:" '::' @Ident "`
}
func (*MethodAccess) expression(){}
func (*MethodAccess) statement(){}
func (this *MethodAccess) String () string {
return fmt.Sprint(this.Source, "::", this.Member)
}
// If/else is a control flow branching expression that executes one of two
// expressions depending on a boolean value. If the value of the if/else is
// unused, the else expression need not be specified. It may be assigned to any

View File

@ -63,7 +63,7 @@ type Method struct {
Pos lexer.Position
Public bool `parser:" @'+'? "`
TypeName string `parser:" @TypeIdent "`
Signature *Signature `parser:" '::' @@ "`
Signature *Signature `parser:" '.' @@ "`
Body Expression `parser:" ( '=' @@ )? "`
// Semantics
@ -76,7 +76,7 @@ func (this *Method) String () string {
return fmt.Sprint(this.TypeName, ".", this.Signature)
} else {
return fmt.Sprint (
this.TypeName, "::",
this.TypeName, ".",
this.Signature, " = ",
this.Body)
}

View File

@ -49,7 +49,7 @@ testString (test,
// correct
`[var] = sdfdf
[memberAccess] = sdfdf.a
[methodAccess] = sdfdf::method
[methodAccess] = sdfdf.[method 238 9 203]
[declaration] = sdfdf:Int
[call] = [print 3 1]
[emptyBlock] = {}
@ -68,7 +68,7 @@ testString (test,
`
[var] = sdfdf
[memberAccess] = sdfdf.a
[methodAccess] = sdfdf::method
[methodAccess] = sdfdf.[method 238 9 203]
[declaration] = sdfdf:Int
[call] = [print 3 1]
[emptyBlock] = { }
@ -128,14 +128,14 @@ func TestMethod (test *testing.T) {
testString (test,
// correct
`BopIt: Int
BopIt::[bop force:UInt] = {}
BopIt::[twist angle:F64] = {}
BopIt::[pull distance:Int] = {}`,
BopIt.[bop force:UInt] = {}
BopIt.[twist angle:F64] = {}
BopIt.[pull distance:Int] = {}`,
//input
`
BopIt: Int
BopIt::[bop force:UInt] = { }
BopIt::[twist angle:F64] = { }
BopIt::[pull distance:Int] = { }
BopIt.[bop force:UInt] = { }
BopIt.[twist angle:F64] = { }
BopIt.[pull distance:Int] = { }
`)
}

View File

@ -29,9 +29,9 @@ var parser = participle.MustBuild[Tree] (
&entity.Return { },
&entity.IfElse { },
&entity.Loop { },
&entity.MethodCall { },
&entity.MemberAccess { },
&entity.Declaration { },
&entity.MethodAccess { },
&entity.Variable { },
&entity.Subscript { },
&entity.Slice { },
@ -43,26 +43,29 @@ var parser = participle.MustBuild[Tree] (
&entity.Call { },
&entity.Block { }),
participle.Union[entity.Statement] (
&entity.LiteralInt { },
&entity.LiteralFloat { },
&entity.LiteralArray { },
&entity.LiteralStruct { },
&entity.Assignment { },
&entity.IfElse { },
&entity.Loop { },
&entity.MemberAccess { },
&entity.Declaration { },
&entity.MethodAccess { },
&entity.Variable { },
&entity.Subscript { },
&entity.Slice { },
&entity.Dereference { },
&entity.Reference { },
&entity.ValueCast { },
&entity.BitCast { },
&entity.Operation { },
&entity.Call { },
&entity.Block { }),
&entity.LiteralInt { },
&entity.LiteralFloat { },
&entity.LiteralArray { },
&entity.LiteralStruct { },
&entity.LiteralBoolean { },
&entity.Break { },
&entity.Return { },
&entity.Assignment { },
&entity.IfElse { },
&entity.Loop { },
&entity.MethodCall { },
&entity.MemberAccess { },
&entity.Declaration { },
&entity.Variable { },
&entity.Subscript { },
&entity.Slice { },
&entity.Dereference { },
&entity.Reference { },
&entity.ValueCast { },
&entity.BitCast { },
&entity.Operation { },
&entity.Call { },
&entity.Block { }),
participle.UseLookahead(participle.MaxLookahead),
participle.Lexer(flexer.NewDefinition()))