Add access specifiers and link names to parser
This commit is contained in:
parent
6bcbd6aff9
commit
0645e2b43a
@ -8,11 +8,36 @@ type TopLevel interface {
|
|||||||
topLevel ()
|
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.
|
// Typedef binds a type to a global identifier.
|
||||||
type Typedef struct {
|
type Typedef struct {
|
||||||
// Syntax
|
// Syntax
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Public bool `parser:" @'+'? "`
|
Acc *Access `parser:" @('-' | '#' | '+')? "`
|
||||||
Name string `parser:" @TypeIdent "`
|
Name string `parser:" @TypeIdent "`
|
||||||
Type Type `parser:" ':' @@ "`
|
Type Type `parser:" ':' @@ "`
|
||||||
|
|
||||||
@ -21,13 +46,17 @@ type Typedef struct {
|
|||||||
}
|
}
|
||||||
func (*Typedef) topLevel(){}
|
func (*Typedef) topLevel(){}
|
||||||
func (this *Typedef) String () string {
|
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 {
|
if this.Methods != nil {
|
||||||
for _, method := range this.Methods {
|
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
|
// Function binds a global identifier and argument list to an expression which
|
||||||
@ -38,8 +67,9 @@ func (this *Typedef) String () string {
|
|||||||
type Function struct {
|
type Function struct {
|
||||||
// Syntax
|
// Syntax
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Public bool `parser:" @'+'? "`
|
Acc *Access `parser:" @('-' | '#' | '+')? "`
|
||||||
Signature *Signature `parser:" @@ "`
|
Signature *Signature `parser:" @@ "`
|
||||||
|
LinkName string `parser:" @String? "`
|
||||||
Body Expression `parser:" ( '=' @@ )? "`
|
Body Expression `parser:" ( '=' @@ )? "`
|
||||||
|
|
||||||
// Semantics
|
// Semantics
|
||||||
@ -47,11 +77,18 @@ type Function struct {
|
|||||||
}
|
}
|
||||||
func (*Function) topLevel(){}
|
func (*Function) topLevel(){}
|
||||||
func (this *Function) String () string {
|
func (this *Function) String () string {
|
||||||
if this.Body == nil {
|
output := ""
|
||||||
return fmt.Sprint(this.Signature)
|
if this.Acc != nil {
|
||||||
} else {
|
output += fmt.Sprint(this.Acc, " ")
|
||||||
return fmt.Sprint(this.Signature, " = ", this.Body)
|
|
||||||
}
|
}
|
||||||
|
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
|
// 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 {
|
type Method struct {
|
||||||
// Syntax
|
// Syntax
|
||||||
Pos lexer.Position
|
Pos lexer.Position
|
||||||
Public bool `parser:" @'+'? "`
|
Acc *Access `parser:" @('-' | '#' | '+')? "`
|
||||||
TypeName string `parser:" @TypeIdent "`
|
TypeName string `parser:" @TypeIdent "`
|
||||||
Signature *Signature `parser:" '.' @@ "`
|
Signature *Signature `parser:" '.' @@ "`
|
||||||
|
LinkName string `parser:" @String? "`
|
||||||
Body Expression `parser:" ( '=' @@ )? "`
|
Body Expression `parser:" ( '=' @@ )? "`
|
||||||
|
|
||||||
// Semantics
|
// Semantics
|
||||||
@ -73,12 +111,16 @@ type Method struct {
|
|||||||
}
|
}
|
||||||
func (*Method) topLevel(){}
|
func (*Method) topLevel(){}
|
||||||
func (this *Method) String () string {
|
func (this *Method) String () string {
|
||||||
if this.Body == nil {
|
output := ""
|
||||||
return fmt.Sprint(this.TypeName, ".", this.Signature)
|
if this.Acc != nil {
|
||||||
} else {
|
output += fmt.Sprint(this.Acc, " ")
|
||||||
return fmt.Sprint (
|
|
||||||
this.TypeName, ".",
|
|
||||||
this.Signature, " = ",
|
|
||||||
this.Body)
|
|
||||||
}
|
}
|
||||||
|
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] = { }
|
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