Add access specifiers and link names to parser
This commit is contained in:
parent
6bcbd6aff9
commit
0645e2b43a
@ -8,26 +8,55 @@ type TopLevel interface {
|
||||
topLevel ()
|
||||
}
|
||||
|
||||
// Access determines the external access rule for a top-level entity.
|
||||
type Access int; const (
|
||||
AccessPrivate = iota
|
||||
AccessRestricted
|
||||
AccessPublic
|
||||
)
|
||||
|
||||
func (this *Access) String () string {
|
||||
switch *this {
|
||||
case AccessPrivate: return "-"
|
||||
case AccessRestricted: return "#"
|
||||
case AccessPublic: return "+"
|
||||
default: return fmt.Sprintf("entity.Access(%d)", this)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Access) Capture (values []string) error {
|
||||
switch values[0] {
|
||||
case "-": *this = AccessPrivate
|
||||
case "#": *this = AccessRestricted
|
||||
case "+": *this = AccessPublic
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Typedef binds a type to a global identifier.
|
||||
type Typedef struct {
|
||||
// Syntax
|
||||
Pos lexer.Position
|
||||
Public bool `parser:" @'+'? "`
|
||||
Name string `parser:" @TypeIdent "`
|
||||
Type Type `parser:" ':' @@ "`
|
||||
Acc *Access `parser:" @('-' | '#' | '+')? "`
|
||||
Name string `parser:" @TypeIdent "`
|
||||
Type Type `parser:" ':' @@ "`
|
||||
|
||||
// Semantics
|
||||
Methods map[string] *Method
|
||||
}
|
||||
func (*Typedef) topLevel(){}
|
||||
func (this *Typedef) String () string {
|
||||
out := fmt.Sprint(this.Name, ": ", this.Type)
|
||||
output := ""
|
||||
if this.Acc != nil {
|
||||
output += fmt.Sprint(this.Acc, " ")
|
||||
}
|
||||
output += fmt.Sprint(this.Name, ": ", this.Type)
|
||||
if this.Methods != nil {
|
||||
for _, method := range this.Methods {
|
||||
out += fmt.Sprint("\n", method)
|
||||
output += fmt.Sprint("\n", method)
|
||||
}
|
||||
}
|
||||
return out
|
||||
return output
|
||||
}
|
||||
|
||||
// Function binds a global identifier and argument list to an expression which
|
||||
@ -38,8 +67,9 @@ func (this *Typedef) String () string {
|
||||
type Function struct {
|
||||
// Syntax
|
||||
Pos lexer.Position
|
||||
Public bool `parser:" @'+'? "`
|
||||
Acc *Access `parser:" @('-' | '#' | '+')? "`
|
||||
Signature *Signature `parser:" @@ "`
|
||||
LinkName string `parser:" @String? "`
|
||||
Body Expression `parser:" ( '=' @@ )? "`
|
||||
|
||||
// Semantics
|
||||
@ -47,11 +77,18 @@ type Function struct {
|
||||
}
|
||||
func (*Function) topLevel(){}
|
||||
func (this *Function) String () string {
|
||||
if this.Body == nil {
|
||||
return fmt.Sprint(this.Signature)
|
||||
} else {
|
||||
return fmt.Sprint(this.Signature, " = ", this.Body)
|
||||
output := ""
|
||||
if this.Acc != nil {
|
||||
output += fmt.Sprint(this.Acc, " ")
|
||||
}
|
||||
output += this.Signature.String()
|
||||
if this.LinkName != "" {
|
||||
output += fmt.Sprint(" '", this.LinkName, "'")
|
||||
}
|
||||
if this.Body != nil {
|
||||
output += fmt.Sprint(" = ", this.Body)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// Method is like a function, except localized to a defined type. Methods are
|
||||
@ -61,9 +98,10 @@ func (this *Function) String () string {
|
||||
type Method struct {
|
||||
// Syntax
|
||||
Pos lexer.Position
|
||||
Public bool `parser:" @'+'? "`
|
||||
Acc *Access `parser:" @('-' | '#' | '+')? "`
|
||||
TypeName string `parser:" @TypeIdent "`
|
||||
Signature *Signature `parser:" '.' @@ "`
|
||||
LinkName string `parser:" @String? "`
|
||||
Body Expression `parser:" ( '=' @@ )? "`
|
||||
|
||||
// Semantics
|
||||
@ -73,12 +111,16 @@ type Method struct {
|
||||
}
|
||||
func (*Method) topLevel(){}
|
||||
func (this *Method) String () string {
|
||||
if this.Body == nil {
|
||||
return fmt.Sprint(this.TypeName, ".", this.Signature)
|
||||
} else {
|
||||
return fmt.Sprint (
|
||||
this.TypeName, ".",
|
||||
this.Signature, " = ",
|
||||
this.Body)
|
||||
output := ""
|
||||
if this.Acc != nil {
|
||||
output += fmt.Sprint(this.Acc, " ")
|
||||
}
|
||||
output += fmt.Sprint(this.TypeName, ".", this.Signature)
|
||||
if this.LinkName != "" {
|
||||
output += fmt.Sprint(" '", this.LinkName, "'")
|
||||
}
|
||||
if this.Body != nil {
|
||||
output += fmt.Sprint(" = ", this.Body)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
@ -143,3 +143,51 @@ BopIt.[twist angle:F64] = { }
|
||||
BopIt.[pull distance:Int] = { }
|
||||
`)
|
||||
}
|
||||
|
||||
func TestAccess (test *testing.T) {
|
||||
testString (test,
|
||||
// correct
|
||||
`+ PublicType: Int
|
||||
# RestrictedType: (x:Int y:Int)
|
||||
- PrivateType: String
|
||||
AlsoPrivateType: Byte
|
||||
+ [publicFn]:Int = 0
|
||||
# [restrictedFn]:(x:Int y:Int) = (x:0 y:0)
|
||||
- [privateFn]:Rune = 'a'
|
||||
[alsoPrivateFn]:Byte = 0
|
||||
T: Int
|
||||
+ T.[publicFn]:Int = 0
|
||||
# T.[restrictedFn]:(x:Int y:Int) = (x:0 y:0)
|
||||
- T.[privateFn]:Rune = 'a'
|
||||
T.[alsoPrivateFn]:Byte = 0`,
|
||||
//input
|
||||
`
|
||||
+ PublicType: Int
|
||||
# RestrictedType: (x:Int y:Int)
|
||||
- PrivateType: String
|
||||
AlsoPrivateType: Byte
|
||||
+ [publicFn]: Int = 0
|
||||
# [restrictedFn]: (x:Int y:Int) = (x:0 y:0)
|
||||
- [privateFn]: Rune = 'a'
|
||||
[alsoPrivateFn]: Byte = 0
|
||||
T: Int
|
||||
+ T.[publicFn]: Int = 0
|
||||
# T.[restrictedFn]: (x:Int y:Int) = (x:0 y:0)
|
||||
- T.[privateFn]: Rune = 'a'
|
||||
T.[alsoPrivateFn]: Byte = 0
|
||||
`)
|
||||
}
|
||||
|
||||
func TestLinkName (test *testing.T) {
|
||||
testString (test,
|
||||
// correct
|
||||
`[puts byte:*:Byte]:Index 'puts'
|
||||
File.[write size:Index nmemb:Index]:Index 'fwrite'
|
||||
[main]:Int 'main' = 0`,
|
||||
// input
|
||||
`
|
||||
[puts byte:*:Byte]: Index 'puts'
|
||||
File.[write size:Index nmemb:Index]: Index 'fwrite'
|
||||
[main]: Int 'main' = 0
|
||||
`)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user