type-section-rework #6
@ -4,6 +4,6 @@ require "io"
|
|||||||
|
|
||||||
func ro main
|
func ro main
|
||||||
> arguments:{String ..}
|
> arguments:{String ..}
|
||||||
< status:Int 0
|
< status:Int:<0>
|
||||||
---
|
---
|
||||||
io.println "hello world"
|
io.println "hello world"
|
||||||
|
@ -5,18 +5,18 @@ require "io"
|
|||||||
---
|
---
|
||||||
|
|
||||||
# this is a global variable
|
# this is a global variable
|
||||||
data pv helloText:String "Hello, world!"
|
data pv helloText:String:<"Hello, world!">
|
||||||
|
|
||||||
# this is a struct definition
|
# this is a struct definition
|
||||||
objt ro Greeter:Obj
|
type ro Greeter:Obj:(
|
||||||
rw text:String "Hi."
|
.rw text:String:<"Hi.">)
|
||||||
|
|
||||||
# this is a function
|
# this is a function
|
||||||
func ro main
|
func ro main
|
||||||
> arguments:{String ..}
|
> arguments:{String ..}
|
||||||
< status:Int 0
|
< status:Int:<0>
|
||||||
---
|
---
|
||||||
= greeter:Greeter:mut
|
let greeter:Greeter:mut
|
||||||
greeter.setText helloText
|
greeter.setText helloText
|
||||||
greeter.greet
|
greeter.greet
|
||||||
|
|
||||||
|
@ -192,6 +192,16 @@ func (lexer *LexingOperation) tokenizeSymbolBeginning () (err error) {
|
|||||||
token.kind = TokenKindComma
|
token.kind = TokenKindComma
|
||||||
lexer.addToken(token)
|
lexer.addToken(token)
|
||||||
err = lexer.nextRune()
|
err = lexer.nextRune()
|
||||||
|
case '(':
|
||||||
|
token := lexer.newToken()
|
||||||
|
token.kind = TokenKindLParen
|
||||||
|
lexer.addToken(token)
|
||||||
|
err = lexer.nextRune()
|
||||||
|
case ')':
|
||||||
|
token := lexer.newToken()
|
||||||
|
token.kind = TokenKindRParen
|
||||||
|
lexer.addToken(token)
|
||||||
|
err = lexer.nextRune()
|
||||||
case '[':
|
case '[':
|
||||||
token := lexer.newToken()
|
token := lexer.newToken()
|
||||||
token.kind = TokenKindLBracket
|
token.kind = TokenKindLBracket
|
||||||
|
@ -138,6 +138,8 @@ func TestTokenizeAll (test *testing.T) {
|
|||||||
quickToken(1, TokenKindDot, nil),
|
quickToken(1, TokenKindDot, nil),
|
||||||
quickToken(1, TokenKindComma, nil),
|
quickToken(1, TokenKindComma, nil),
|
||||||
quickToken(2, TokenKindElipsis, nil),
|
quickToken(2, TokenKindElipsis, nil),
|
||||||
|
quickToken(1, TokenKindLParen, nil),
|
||||||
|
quickToken(1, TokenKindRParen, nil),
|
||||||
quickToken(1, TokenKindLBracket, nil),
|
quickToken(1, TokenKindLBracket, nil),
|
||||||
quickToken(1, TokenKindRBracket, nil),
|
quickToken(1, TokenKindRBracket, nil),
|
||||||
quickToken(1, TokenKindLBrace, nil),
|
quickToken(1, TokenKindLBrace, nil),
|
||||||
|
@ -28,6 +28,8 @@ const (
|
|||||||
TokenKindElipsis
|
TokenKindElipsis
|
||||||
TokenKindComma
|
TokenKindComma
|
||||||
|
|
||||||
|
TokenKindLParen
|
||||||
|
TokenKindRParen
|
||||||
TokenKindLBracket
|
TokenKindLBracket
|
||||||
TokenKindRBracket
|
TokenKindRBracket
|
||||||
TokenKindLBrace
|
TokenKindLBrace
|
||||||
@ -166,6 +168,10 @@ func (tokenKind TokenKind) Describe () (description string) {
|
|||||||
description = "Elipsis"
|
description = "Elipsis"
|
||||||
case TokenKindComma:
|
case TokenKindComma:
|
||||||
description = "Comma"
|
description = "Comma"
|
||||||
|
case TokenKindLParen:
|
||||||
|
description = "LParen"
|
||||||
|
case TokenKindRParen:
|
||||||
|
description = "RParen"
|
||||||
case TokenKindLBracket:
|
case TokenKindLBracket:
|
||||||
description = "LBracket"
|
description = "LBracket"
|
||||||
case TokenKindRBracket:
|
case TokenKindRBracket:
|
||||||
|
@ -29,12 +29,6 @@ func (section TypeSection) Kind () (kind SectionKind) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kind returns the section's kind (SectionKindObjt).
|
|
||||||
func (section ObjtSection) Kind () (kind SectionKind) {
|
|
||||||
kind = SectionKindObjt
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind returns the section's kind (SectionKindEnum).
|
// Kind returns the section's kind (SectionKindEnum).
|
||||||
func (section EnumSection) Kind () (kind SectionKind) {
|
func (section EnumSection) Kind () (kind SectionKind) {
|
||||||
kind = SectionKindEnum
|
kind = SectionKindEnum
|
||||||
@ -111,23 +105,23 @@ func (what Type) Points () (points Type) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values returns an iterator for the initialization values.
|
// MembersLength returns the amount of new members the type specifier defines.
|
||||||
func (values ObjectInitializationValues) Sections () (
|
// If it defines no new members, it returns zero.
|
||||||
iterator types.Iterator[Argument],
|
func (what Type) MembersLength () (length int) {
|
||||||
) {
|
length = len(what.members)
|
||||||
iterator = types.NewIterator(values.attributes)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length returns the amount of values.
|
// Member returns the member at index.
|
||||||
func (values ArrayInitializationValues) Length () (length int) {
|
func (what Type) Member (index int) (member TypeMember) {
|
||||||
length = len(values.values)
|
member = what.members[index]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item returns the value at index.
|
// BitWidth returns the bit width of the type member. If it is zero, it should
|
||||||
func (values ArrayInitializationValues) Value (index int) (value Argument) {
|
// be treated as unspecified.
|
||||||
value = values.values[index]
|
func (member TypeMember) BitWidth () (width uint64) {
|
||||||
|
width = member.bitWidth
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,25 +138,6 @@ func (argument Argument) Value () (value any) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// BitWidth returns the bit width of the object member. If it is zero, it should
|
|
||||||
// be treated as unspecified.
|
|
||||||
func (member ObjtMember) BitWidth () (width uint64) {
|
|
||||||
width = member.bitWidth
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Length returns the amount of members in the section.
|
|
||||||
func (section ObjtSection) Length () (length int) {
|
|
||||||
length = len(section.members)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Item returns the member at index.
|
|
||||||
func (section ObjtSection) Item (index int) (member ObjtMember) {
|
|
||||||
member = section.members[index]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Length returns the amount of members in the section.
|
// Length returns the amount of members in the section.
|
||||||
func (section EnumSection) Length () (length int) {
|
func (section EnumSection) Length () (length int) {
|
||||||
length = len(section.members)
|
length = len(section.members)
|
||||||
@ -272,12 +247,6 @@ func (section FuncSection) OutputsLength () (length int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output returns the output at index.
|
|
||||||
func (section FuncSection) Output (index int) (output FuncOutput) {
|
|
||||||
output = section.outputs[index]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Root returns the root block of the section.
|
// Root returns the root block of the section.
|
||||||
func (section FuncSection) Root () (root Block) {
|
func (section FuncSection) Root () (root Block) {
|
||||||
root = section.root
|
root = section.root
|
||||||
|
@ -23,12 +23,6 @@ func (parser *ParsingOperation) parseBody () (err error) {
|
|||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
if parseErr != nil { return parseErr }
|
if parseErr != nil { return parseErr }
|
||||||
|
|
||||||
case "objt":
|
|
||||||
section, parseErr := parser.parseObjtSection()
|
|
||||||
err = parser.tree.addSection(section)
|
|
||||||
if err != nil { return }
|
|
||||||
if parseErr != nil { return parseErr }
|
|
||||||
|
|
||||||
case "face":
|
case "face":
|
||||||
section, parseErr := parser.parseFaceSection()
|
section, parseErr := parser.parseFaceSection()
|
||||||
err = parser.tree.addSection(section)
|
err = parser.tree.addSection(section)
|
||||||
|
@ -35,18 +35,18 @@ func (parser *ParsingOperation) parseDataSection () (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
err = parser.expect(lexer.TokenKindNewline)
|
||||||
|
if err != nil { return }
|
||||||
err = parser.nextToken()
|
err = parser.nextToken()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
// check if external
|
// check if data is external
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
if parser.token.Is(lexer.TokenKindIndent) &&
|
||||||
if parser.token.Value().(int) != 1 { return }
|
parser.token.Value().(int) == 1 {
|
||||||
|
|
||||||
err = parser.nextToken()
|
err = parser.nextToken(lexer.TokenKindName)
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
if parser.token.Is(lexer.TokenKindName) &&
|
if parser.token.Value().(string) == "external" {
|
||||||
parser.token.Value().(string) == "external" {
|
|
||||||
|
|
||||||
section.external = true
|
section.external = true
|
||||||
err = parser.nextToken(lexer.TokenKindNewline)
|
err = parser.nextToken(lexer.TokenKindNewline)
|
||||||
@ -56,18 +56,7 @@ func (parser *ParsingOperation) parseDataSection () (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, parse initialization values
|
|
||||||
parser.previousToken()
|
parser.previousToken()
|
||||||
section.value, err = parser.parseInitializationValues(0)
|
|
||||||
if err != nil { return }
|
|
||||||
} else {
|
|
||||||
section.value, err = parser.parseArgument()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
err = parser.expect(lexer.TokenKindNewline)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,14 @@ func TestData (test *testing.T) {
|
|||||||
checkTree ("../tests/parser/data", false,
|
checkTree ("../tests/parser/data", false,
|
||||||
`:arf
|
`:arf
|
||||||
---
|
---
|
||||||
data ro aInteger:Int 3202
|
data ro aInteger:Int:<3202>
|
||||||
data ro bMutInteger:Int:mut 3202
|
data ro bMutInteger:Int:mut:<3202>
|
||||||
data ro cIntegerPointer:{Int}
|
data ro cIntegerPointer:{Int}
|
||||||
data ro dMutIntegerPointer:{Int}:mut
|
data ro dMutIntegerPointer:{Int}:mut
|
||||||
data ro eIntegerArray16:Int:16
|
data ro eIntegerArray16:Int:16
|
||||||
data ro fIntegerArrayVariable:{Int ..}
|
data ro fIntegerArrayVariable:{Int ..}
|
||||||
data ro gIntegerArrayInitialized:Int:16
|
data ro gIntegerArrayInitialized:Int:16:
|
||||||
|
<
|
||||||
3948
|
3948
|
||||||
293
|
293
|
||||||
293049
|
293049
|
||||||
@ -24,20 +25,35 @@ data ro gIntegerArrayInitialized:Int:16
|
|||||||
0
|
0
|
||||||
4785
|
4785
|
||||||
92
|
92
|
||||||
data ro jObject:thing.Thing.thing.thing
|
>
|
||||||
.that 2139
|
data rw hIntegerPointerInit:{Int}:<[& integer]>
|
||||||
.this 324
|
data rw iMutIntegerPointerInit:{Int}:mut:<[& integer]>
|
||||||
data ro kNestedObject:Obj
|
data ro jObject:Obj:
|
||||||
.that
|
(
|
||||||
.bird2 123.8439
|
.that:<324>
|
||||||
.bird3 9328.21348239
|
.this:<324>
|
||||||
.this
|
)
|
||||||
.bird0 324
|
data ro kNestedObject:Obj:
|
||||||
.bird1 "hello world"
|
(
|
||||||
|
.ro newMember:Int:<9023>
|
||||||
|
):
|
||||||
|
(
|
||||||
|
.that:
|
||||||
|
(
|
||||||
|
.bird2:<123.8439>
|
||||||
|
.bird3:<9328.21348239>
|
||||||
|
)
|
||||||
|
.this:
|
||||||
|
(
|
||||||
|
.bird0:<324>
|
||||||
|
.bird1:<"hello world">
|
||||||
|
)
|
||||||
|
)
|
||||||
data ro lMutIntegerArray16:Int:16:mut
|
data ro lMutIntegerArray16:Int:16:mut
|
||||||
data ro mExternalData:Int:8
|
data ro mExternalData:Int:8
|
||||||
external
|
external
|
||||||
data ro nIntegerArrayInitialized:Int:16:mut
|
data ro nIntegerArrayInitialized:Int:16:mut:
|
||||||
|
<
|
||||||
3948
|
3948
|
||||||
293
|
293
|
||||||
293049
|
293049
|
||||||
@ -49,5 +65,6 @@ data ro nIntegerArrayInitialized:Int:16:mut
|
|||||||
0
|
0
|
||||||
4785
|
4785
|
||||||
92
|
92
|
||||||
|
>
|
||||||
`, test)
|
`, test)
|
||||||
}
|
}
|
||||||
|
180
parser/default-values.go
Normal file
180
parser/default-values.go
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package parser
|
||||||
|
//
|
||||||
|
// import "git.tebibyte.media/arf/arf/lexer"
|
||||||
|
// import "git.tebibyte.media/arf/arf/infoerr"
|
||||||
|
//
|
||||||
|
// // TODO:
|
||||||
|
// // (parser *ParsingOperation) parseDefaultValues
|
||||||
|
//
|
||||||
|
// // (parser *ParsingOperation) parseDefaultMemberValues (return tree of new members and a tree of member values)
|
||||||
|
// // (parser *ParsingOperation) parseDefaultArrayValues
|
||||||
|
//
|
||||||
|
// // (parser *ParsingOperation) parseDefaultMemberValue
|
||||||
|
// // (parser *ParsingOperation) parseMemberDeclaration
|
||||||
|
//
|
||||||
|
// // parsedefaultValues starts on the line after a = phrase, a data section, a
|
||||||
|
// // type section, or anywhere else where there can be a default value. It returns
|
||||||
|
// // a default value in the form of an argument, as well as any defined members
|
||||||
|
// // that it finds.
|
||||||
|
// func (parser *ParsingOperation) parseDefaultValues (
|
||||||
|
// baseIndent int,
|
||||||
|
// ) (
|
||||||
|
// argument Argument,
|
||||||
|
// members []TypeMember,
|
||||||
|
// err error,
|
||||||
|
// ) {
|
||||||
|
// // check if line is indented one more than baseIndent
|
||||||
|
// if !parser.token.Is(lexer.TokenKindIndent) { return }
|
||||||
|
// if parser.token.Value().(int) != baseIndent + 1 { return }
|
||||||
|
//
|
||||||
|
// argument.location = parser.token.Location()
|
||||||
|
//
|
||||||
|
// err = parser.nextToken()
|
||||||
|
// if err != nil { return }
|
||||||
|
//
|
||||||
|
// if parser.token.Is(lexer.TokenKindDot) {
|
||||||
|
//
|
||||||
|
// // object initialization
|
||||||
|
// parser.previousToken()
|
||||||
|
// var values ObjectDefaultValues
|
||||||
|
// values, err = parser.parseObjectdefaultValues()
|
||||||
|
// argument.kind = ArgumentKindObjectDefaultValues
|
||||||
|
// argument.value = values
|
||||||
|
//
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// // array initialization
|
||||||
|
// parser.previousToken()
|
||||||
|
// var values ArrayDefaultValues
|
||||||
|
// values, err = parser.parseArrayDefaultValues()
|
||||||
|
// argument.kind = ArgumentKindArrayDefaultValues
|
||||||
|
// argument.value = values
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // parseObjectdefaultValues parses a list of object initialization
|
||||||
|
// // values until the indentation level drops.
|
||||||
|
// func (parser *ParsingOperation) parseObjectdefaultValues () (
|
||||||
|
// defaultValues ObjectDefaultValues,
|
||||||
|
// err error,
|
||||||
|
// ) {
|
||||||
|
// defaultValues.attributes = make(map[string] Argument)
|
||||||
|
//
|
||||||
|
// baseIndent := 0
|
||||||
|
// begin := true
|
||||||
|
//
|
||||||
|
// for {
|
||||||
|
// // if there is no indent we can just stop parsing
|
||||||
|
// if !parser.token.Is(lexer.TokenKindIndent) { break}
|
||||||
|
// indent := parser.token.Value().(int)
|
||||||
|
//
|
||||||
|
// if begin == true {
|
||||||
|
// defaultValues.location = parser.token.Location()
|
||||||
|
// baseIndent = indent
|
||||||
|
// begin = false
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // do not parse any further if the indent has changed
|
||||||
|
// if indent != baseIndent { break }
|
||||||
|
//
|
||||||
|
// // move on to the beginning of the line, which must contain
|
||||||
|
// // a member initialization value
|
||||||
|
// err = parser.nextToken(lexer.TokenKindDot)
|
||||||
|
// if err != nil { return }
|
||||||
|
// err = parser.nextToken(lexer.TokenKindName)
|
||||||
|
// if err != nil { return }
|
||||||
|
// name := parser.token.Value().(string)
|
||||||
|
//
|
||||||
|
// // if the member has already been listed, throw an error
|
||||||
|
// _, exists := defaultValues.attributes[name]
|
||||||
|
// if exists {
|
||||||
|
// err = parser.token.NewError (
|
||||||
|
// "duplicate member \"" + name + "\" in object " +
|
||||||
|
// "member initialization",
|
||||||
|
// infoerr.ErrorKindError)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // parse the argument determining the member initialization
|
||||||
|
// // value
|
||||||
|
// err = parser.nextToken()
|
||||||
|
// if err != nil { return }
|
||||||
|
// var value Argument
|
||||||
|
// if parser.token.Is(lexer.TokenKindNewline) {
|
||||||
|
//
|
||||||
|
// // recurse
|
||||||
|
// err = parser.nextToken(lexer.TokenKindIndent)
|
||||||
|
// if err != nil { return }
|
||||||
|
//
|
||||||
|
// value, err = parser.parseDefaultValues(baseIndent)
|
||||||
|
// defaultValues.attributes[name] = value
|
||||||
|
// if err != nil { return }
|
||||||
|
//
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// // parse as normal argument
|
||||||
|
// value, err = parser.parseArgument()
|
||||||
|
// defaultValues.attributes[name] = value
|
||||||
|
// if err != nil { return }
|
||||||
|
//
|
||||||
|
// err = parser.expect(lexer.TokenKindNewline)
|
||||||
|
// if err != nil { return }
|
||||||
|
// err = parser.nextToken()
|
||||||
|
// if err != nil { return }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // parseArrayDefaultValues parses a list of array initialization values until
|
||||||
|
// // the indentation lexel drops.
|
||||||
|
// func (parser *ParsingOperation) parseArrayDefaultValues () (
|
||||||
|
// defaultValues ArrayDefaultValues,
|
||||||
|
// err error,
|
||||||
|
// ) {
|
||||||
|
// baseIndent := 0
|
||||||
|
// begin := true
|
||||||
|
//
|
||||||
|
// for {
|
||||||
|
// // if there is no indent we can just stop parsing
|
||||||
|
// if !parser.token.Is(lexer.TokenKindIndent) { break}
|
||||||
|
// indent := parser.token.Value().(int)
|
||||||
|
//
|
||||||
|
// if begin == true {
|
||||||
|
// defaultValues.location = parser.token.Location()
|
||||||
|
// baseIndent = indent
|
||||||
|
// begin = false
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // do not parse any further if the indent has changed
|
||||||
|
// if indent != baseIndent { break }
|
||||||
|
//
|
||||||
|
// // move on to the beginning of the line, which must contain
|
||||||
|
// // arguments
|
||||||
|
// err = parser.nextToken(validArgumentStartTokens...)
|
||||||
|
// if err != nil { return }
|
||||||
|
//
|
||||||
|
// for {
|
||||||
|
// // stop parsing this line and go on to the next if a
|
||||||
|
// // newline token is encountered
|
||||||
|
// if parser.token.Is(lexer.TokenKindNewline) {
|
||||||
|
// err = parser.nextToken()
|
||||||
|
// if err != nil { return }
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // otherwise, parse the argument
|
||||||
|
// var argument Argument
|
||||||
|
// argument, err = parser.parseArgument()
|
||||||
|
// if err != nil { return }
|
||||||
|
// defaultValues.values = append (
|
||||||
|
// defaultValues.values,
|
||||||
|
// argument)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return
|
||||||
|
// }
|
@ -61,27 +61,11 @@ func (parser *ParsingOperation) parseEnumMembers (
|
|||||||
// if we've left the block, stop parsing
|
// if we've left the block, stop parsing
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
||||||
if parser.token.Value().(int) != 1 { return }
|
if parser.token.Value().(int) != 1 { return }
|
||||||
|
err = parser.nextToken(lexer.TokenKindMinus)
|
||||||
member := EnumMember { }
|
|
||||||
|
|
||||||
// get name
|
|
||||||
err = parser.nextToken(lexer.TokenKindName)
|
|
||||||
if err != nil { return }
|
|
||||||
member.location = parser.token.Location()
|
|
||||||
member.name = parser.token.Value().(string)
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
// parse default value
|
var member EnumMember
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
member, err = parser.parseEnumMember()
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
member.value, err = parser.parseInitializationValues(1)
|
|
||||||
into.members = append(into.members, member)
|
|
||||||
if err != nil { return }
|
|
||||||
} else {
|
|
||||||
member.value, err = parser.parseArgument()
|
|
||||||
into.members = append(into.members, member)
|
into.members = append(into.members, member)
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
@ -91,4 +75,48 @@ func (parser *ParsingOperation) parseEnumMembers (
|
|||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseEnumMember parses a single enum member. Indenttion level is assumed.
|
||||||
|
func (parser *ParsingOperation) parseEnumMember () (
|
||||||
|
member EnumMember,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
err = parser.expect(lexer.TokenKindMinus)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
// get name
|
||||||
|
err = parser.nextToken(lexer.TokenKindName)
|
||||||
|
if err != nil { return }
|
||||||
|
member.location = parser.token.Location()
|
||||||
|
member.name = parser.token.Value().(string)
|
||||||
|
|
||||||
|
// see if value exists
|
||||||
|
err = parser.nextToken (
|
||||||
|
lexer.TokenKindColon,
|
||||||
|
lexer.TokenKindNewline)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindColon) {
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
err = parser.skipWhitespace()
|
||||||
|
if err != nil { return }
|
||||||
|
err = parser.expect (
|
||||||
|
lexer.TokenKindLessThan,
|
||||||
|
lexer.TokenKindLParen)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindLessThan) {
|
||||||
|
// parse value
|
||||||
|
member.value, err = parser.parseBasicDefaultValue()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
} else if parser.token.Is(lexer.TokenKindLParen) {
|
||||||
|
// parse default values
|
||||||
|
member.value, err = parser.parseObjectDefaultValue()
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,63 @@ func TestEnum (test *testing.T) {
|
|||||||
`:arf
|
`:arf
|
||||||
---
|
---
|
||||||
enum ro AffrontToGod:Int:4
|
enum ro AffrontToGod:Int:4
|
||||||
bird0
|
- bird0:
|
||||||
|
<
|
||||||
28394
|
28394
|
||||||
9328
|
9328
|
||||||
398
|
398
|
||||||
9
|
9
|
||||||
bird1
|
>
|
||||||
|
- bird1:
|
||||||
|
<
|
||||||
23
|
23
|
||||||
932832
|
932832
|
||||||
398
|
398
|
||||||
2349
|
2349
|
||||||
bird2
|
>
|
||||||
|
- bird2:
|
||||||
|
<
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
4
|
4
|
||||||
|
>
|
||||||
enum ro NamedColor:U32
|
enum ro NamedColor:U32
|
||||||
red 16711680
|
- red:<16711680>
|
||||||
green 65280
|
- green:<65280>
|
||||||
blue 255
|
- blue:<255>
|
||||||
|
enum ro ThisIsTerrible:Obj:
|
||||||
|
(
|
||||||
|
.rw x:Int
|
||||||
|
.rw y:Int
|
||||||
|
)
|
||||||
|
- up:
|
||||||
|
(
|
||||||
|
.x:<0>
|
||||||
|
.y:<-1>
|
||||||
|
)
|
||||||
|
- down:
|
||||||
|
(
|
||||||
|
.x:<0>
|
||||||
|
.y:<1>
|
||||||
|
)
|
||||||
|
- left:
|
||||||
|
(
|
||||||
|
.x:<-1>
|
||||||
|
.y:<0>
|
||||||
|
)
|
||||||
|
- right:
|
||||||
|
(
|
||||||
|
.x:<1>
|
||||||
|
.y:<0>
|
||||||
|
)
|
||||||
enum ro Weekday:Int
|
enum ro Weekday:Int
|
||||||
sunday
|
- sunday
|
||||||
monday
|
- monday
|
||||||
tuesday
|
- tuesday
|
||||||
wednesday
|
- wednesday
|
||||||
thursday
|
- thursday
|
||||||
friday
|
- friday
|
||||||
saturday
|
- saturday
|
||||||
`, test)
|
`, test)
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ func (parser *ParsingOperation) parseFuncArguments (
|
|||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
case lexer.TokenKindLessThan:
|
case lexer.TokenKindLessThan:
|
||||||
output := FuncOutput { }
|
output := Declaration { }
|
||||||
output.location = parser.token.Location()
|
output.location = parser.token.Location()
|
||||||
|
|
||||||
// get name
|
// get name
|
||||||
@ -187,33 +187,12 @@ func (parser *ParsingOperation) parseFuncArguments (
|
|||||||
output.what, err = parser.parseType()
|
output.what, err = parser.parseType()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
// skip the default value if we are skimming
|
|
||||||
if parser.skimming {
|
|
||||||
err = parser.skipIndentLevel(2)
|
|
||||||
into.outputs = append(into.outputs, output)
|
into.outputs = append(into.outputs, output)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse default value
|
parser.expect(lexer.TokenKindNewline)
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
output.value, err =
|
|
||||||
parser.parseInitializationValues(1)
|
|
||||||
into.outputs = append(into.outputs, output)
|
|
||||||
if err != nil { return }
|
|
||||||
} else {
|
|
||||||
output.value, err =
|
|
||||||
parser.parseArgument()
|
|
||||||
into.outputs = append(into.outputs, output)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
err = parser.expect(lexer.TokenKindNewline)
|
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
err = parser.nextToken()
|
err = parser.nextToken()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -8,13 +8,13 @@ func TestFunc (test *testing.T) {
|
|||||||
---
|
---
|
||||||
func ro aBasicExternal
|
func ro aBasicExternal
|
||||||
> someInput:Int:mut
|
> someInput:Int:mut
|
||||||
< someOutput:Int 4
|
< someOutput:Int:<4>
|
||||||
---
|
---
|
||||||
external
|
external
|
||||||
func ro bMethod
|
func ro bMethod
|
||||||
@ bird:{Bird}
|
@ bird:{Bird}
|
||||||
> someInput:Int:mut
|
> someInput:Int:mut
|
||||||
< someOutput:Int 4
|
< someOutput:Int:<4>
|
||||||
---
|
---
|
||||||
external
|
external
|
||||||
func ro cBasicPhrases
|
func ro cBasicPhrases
|
||||||
@ -101,20 +101,9 @@ func ro gControlFlow
|
|||||||
[otherThing]
|
[otherThing]
|
||||||
func ro hSetPhrase
|
func ro hSetPhrase
|
||||||
---
|
---
|
||||||
[= x:Int 3]
|
[let x:Int:<3>]
|
||||||
[= y:{Int} [loc x]]
|
[let y:{Int}:<[loc x]>]
|
||||||
[= z:Int:8]
|
[let z:Int:8:<398 9 2309 983 -2387 478 555 123>]
|
||||||
398
|
[let bird:Bird:(.that:(.whenYou:<99999>) .this:<324>)]
|
||||||
9
|
|
||||||
2309
|
|
||||||
983
|
|
||||||
-2387
|
|
||||||
478
|
|
||||||
555
|
|
||||||
123
|
|
||||||
[= bird:Bird]
|
|
||||||
.that
|
|
||||||
.whenYou 99999
|
|
||||||
.this 324
|
|
||||||
`, test)
|
`, test)
|
||||||
}
|
}
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import "git.tebibyte.media/arf/arf/lexer"
|
|
||||||
import "git.tebibyte.media/arf/arf/infoerr"
|
|
||||||
|
|
||||||
// parseInitializationValues starts on the line after a data section, or a set
|
|
||||||
// phrase. It checks for an indent greater than the indent of the aforementioned
|
|
||||||
// data section or set phrase (passed through baseIndent), and if there is,
|
|
||||||
// it parses initialization values.
|
|
||||||
func (parser *ParsingOperation) parseInitializationValues (
|
|
||||||
baseIndent int,
|
|
||||||
) (
|
|
||||||
initializationArgument Argument,
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
// check if line is indented one more than baseIndent
|
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
|
||||||
if parser.token.Value().(int) != baseIndent + 1 { return }
|
|
||||||
|
|
||||||
initializationArgument.location = parser.token.Location()
|
|
||||||
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
if parser.token.Is(lexer.TokenKindDot) {
|
|
||||||
|
|
||||||
// object initialization
|
|
||||||
parser.previousToken()
|
|
||||||
var initializationValues ObjectInitializationValues
|
|
||||||
initializationValues, err = parser.parseObjectInitializationValues()
|
|
||||||
initializationArgument.kind = ArgumentKindObjectInitializationValues
|
|
||||||
initializationArgument.value = initializationValues
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// array initialization
|
|
||||||
parser.previousToken()
|
|
||||||
var initializationValues ArrayInitializationValues
|
|
||||||
initializationValues, err = parser.parseArrayInitializationValues()
|
|
||||||
initializationArgument.kind = ArgumentKindArrayInitializationValues
|
|
||||||
initializationArgument.value = initializationValues
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseObjectInitializationValues parses a list of object initialization
|
|
||||||
// values until the indentation level drops.
|
|
||||||
func (parser *ParsingOperation) parseObjectInitializationValues () (
|
|
||||||
initializationValues ObjectInitializationValues,
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
initializationValues.attributes = make(map[string] Argument)
|
|
||||||
|
|
||||||
baseIndent := 0
|
|
||||||
begin := true
|
|
||||||
|
|
||||||
for {
|
|
||||||
// if there is no indent we can just stop parsing
|
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { break}
|
|
||||||
indent := parser.token.Value().(int)
|
|
||||||
|
|
||||||
if begin == true {
|
|
||||||
initializationValues.location = parser.token.Location()
|
|
||||||
baseIndent = indent
|
|
||||||
begin = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not parse any further if the indent has changed
|
|
||||||
if indent != baseIndent { break }
|
|
||||||
|
|
||||||
// move on to the beginning of the line, which must contain
|
|
||||||
// a member initialization value
|
|
||||||
err = parser.nextToken(lexer.TokenKindDot)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken(lexer.TokenKindName)
|
|
||||||
if err != nil { return }
|
|
||||||
name := parser.token.Value().(string)
|
|
||||||
|
|
||||||
// if the member has already been listed, throw an error
|
|
||||||
_, exists := initializationValues.attributes[name]
|
|
||||||
if exists {
|
|
||||||
err = parser.token.NewError (
|
|
||||||
"duplicate member \"" + name + "\" in object " +
|
|
||||||
"member initialization",
|
|
||||||
infoerr.ErrorKindError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the argument determining the member initialization
|
|
||||||
// value
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
var value Argument
|
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
|
||||||
|
|
||||||
// recurse
|
|
||||||
err = parser.nextToken(lexer.TokenKindIndent)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
value, err = parser.parseInitializationValues(baseIndent)
|
|
||||||
initializationValues.attributes[name] = value
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// parse as normal argument
|
|
||||||
value, err = parser.parseArgument()
|
|
||||||
initializationValues.attributes[name] = value
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
err = parser.expect(lexer.TokenKindNewline)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseArrayInitializationValues parses a list of array initialization values
|
|
||||||
// until the indentation lexel drops.
|
|
||||||
func (parser *ParsingOperation) parseArrayInitializationValues () (
|
|
||||||
initializationValues ArrayInitializationValues,
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
baseIndent := 0
|
|
||||||
begin := true
|
|
||||||
|
|
||||||
for {
|
|
||||||
// if there is no indent we can just stop parsing
|
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { break}
|
|
||||||
indent := parser.token.Value().(int)
|
|
||||||
|
|
||||||
if begin == true {
|
|
||||||
initializationValues.location = parser.token.Location()
|
|
||||||
baseIndent = indent
|
|
||||||
begin = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not parse any further if the indent has changed
|
|
||||||
if indent != baseIndent { break }
|
|
||||||
|
|
||||||
// move on to the beginning of the line, which must contain
|
|
||||||
// arguments
|
|
||||||
err = parser.nextToken(validArgumentStartTokens...)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
for {
|
|
||||||
// stop parsing this line and go on to the next if a
|
|
||||||
// newline token is encountered
|
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, parse the argument
|
|
||||||
var argument Argument
|
|
||||||
argument, err = parser.parseArgument()
|
|
||||||
if err != nil { return }
|
|
||||||
initializationValues.values = append (
|
|
||||||
initializationValues.values,
|
|
||||||
argument)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
@ -12,7 +12,7 @@ author "Sasha Koshka"
|
|||||||
license "GPLv3"
|
license "GPLv3"
|
||||||
require "` + filepath.Join(cwd, "./some/local/module") + `"
|
require "` + filepath.Join(cwd, "./some/local/module") + `"
|
||||||
require "/some/absolute/path/to/someModule"
|
require "/some/absolute/path/to/someModule"
|
||||||
require "/usr/include/arf/someLibraryInstalledInStandardLocation"
|
require "/usr/local/include/arf/someLibraryInstalledInStandardLocation"
|
||||||
---
|
---
|
||||||
`, test)
|
`, test)
|
||||||
}
|
}
|
||||||
|
@ -1,74 +1,6 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
import "git.tebibyte.media/arf/arf/lexer"
|
import "git.tebibyte.media/arf/arf/lexer"
|
||||||
import "git.tebibyte.media/arf/arf/infoerr"
|
|
||||||
|
|
||||||
// parseType parses a type notation of the form Name, {Name}, etc.
|
|
||||||
func (parser *ParsingOperation) parseType () (what Type, err error) {
|
|
||||||
err = parser.expect(lexer.TokenKindName, lexer.TokenKindLBrace)
|
|
||||||
if err != nil { return }
|
|
||||||
what.location = parser.token.Location()
|
|
||||||
|
|
||||||
if parser.token.Is(lexer.TokenKindLBrace) {
|
|
||||||
what.kind = TypeKindPointer
|
|
||||||
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
var points Type
|
|
||||||
points, err = parser.parseType()
|
|
||||||
if err != nil { return }
|
|
||||||
what.points = &points
|
|
||||||
|
|
||||||
err = parser.expect (
|
|
||||||
lexer.TokenKindRBrace,
|
|
||||||
lexer.TokenKindElipsis)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
if parser.token.Is(lexer.TokenKindElipsis) {
|
|
||||||
what.kind = TypeKindVariableArray
|
|
||||||
|
|
||||||
err = parser.nextToken(lexer.TokenKindRBrace)
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
} else {
|
|
||||||
what.name, err = parser.parseIdentifier()
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
if !parser.token.Is(lexer.TokenKindColon) { break }
|
|
||||||
|
|
||||||
err = parser.nextToken(lexer.TokenKindName, lexer.TokenKindUInt)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
if parser.token.Is(lexer.TokenKindName) {
|
|
||||||
// parse type qualifier
|
|
||||||
qualifier := parser.token.Value().(string)
|
|
||||||
switch qualifier {
|
|
||||||
case "mut":
|
|
||||||
what.mutable = true
|
|
||||||
default:
|
|
||||||
err = parser.token.NewError (
|
|
||||||
"unknown type qualifier \"" +
|
|
||||||
qualifier + "\"",
|
|
||||||
infoerr.ErrorKindError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// parse fixed array length
|
|
||||||
what.length = parser.token.Value().(uint64)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseIdentifier parses an identifier made out of dot separated names.
|
// parseIdentifier parses an identifier made out of dot separated names.
|
||||||
func (parser *ParsingOperation) parseIdentifier () (
|
func (parser *ParsingOperation) parseIdentifier () (
|
||||||
@ -80,7 +12,10 @@ func (parser *ParsingOperation) parseIdentifier () (
|
|||||||
identifier.location = parser.token.Location()
|
identifier.location = parser.token.Location()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if !parser.token.Is(lexer.TokenKindName) { break }
|
if !parser.token.Is(lexer.TokenKindName) {
|
||||||
|
parser.previousToken()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
identifier.trail = append (
|
identifier.trail = append (
|
||||||
identifier.trail,
|
identifier.trail,
|
||||||
|
125
parser/objt.go
125
parser/objt.go
@ -1,125 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import "git.tebibyte.media/arf/arf/types"
|
|
||||||
import "git.tebibyte.media/arf/arf/lexer"
|
|
||||||
import "git.tebibyte.media/arf/arf/infoerr"
|
|
||||||
|
|
||||||
// parseObjtSection parses an object type definition. This allows for structured
|
|
||||||
// types to be defined, and for member variables to be added and overridden.
|
|
||||||
func (parser *ParsingOperation) parseObjtSection () (
|
|
||||||
section ObjtSection,
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
err = parser.expect(lexer.TokenKindName)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
section.location = parser.token.Location()
|
|
||||||
|
|
||||||
// get permission
|
|
||||||
err = parser.nextToken(lexer.TokenKindPermission)
|
|
||||||
if err != nil { return }
|
|
||||||
section.permission = parser.token.Value().(types.Permission)
|
|
||||||
|
|
||||||
// get name
|
|
||||||
err = parser.nextToken(lexer.TokenKindName)
|
|
||||||
if err != nil { return }
|
|
||||||
section.name = parser.token.Value().(string)
|
|
||||||
|
|
||||||
// parse inherited type
|
|
||||||
err = parser.nextToken(lexer.TokenKindColon)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
section.inherits, err = parser.parseIdentifier()
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.expect(lexer.TokenKindNewline)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
// parse members
|
|
||||||
err = parser.parseObjtMembers(§ion)
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
if len(section.members) == 0 {
|
|
||||||
infoerr.NewError (
|
|
||||||
section.location,
|
|
||||||
"defining an object with no members",
|
|
||||||
infoerr.ErrorKindWarn).Print()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseObjtMembers parses a list of members for an object section. Indentation
|
|
||||||
// level is assumed.
|
|
||||||
func (parser *ParsingOperation) parseObjtMembers (
|
|
||||||
into *ObjtSection,
|
|
||||||
) (
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
for {
|
|
||||||
// if we've left the block, stop parsing
|
|
||||||
if !parser.token.Is(lexer.TokenKindIndent) { return }
|
|
||||||
if parser.token.Value().(int) != 1 { return }
|
|
||||||
|
|
||||||
// add member to object section
|
|
||||||
var member ObjtMember
|
|
||||||
member, err = parser.parseObjtMember()
|
|
||||||
into.members = append(into.members, member)
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseObjtMember parses a single member of an object section. Indentation
|
|
||||||
// level is assumed.
|
|
||||||
func (parser *ParsingOperation) parseObjtMember () (
|
|
||||||
member ObjtMember,
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
// get permission
|
|
||||||
err = parser.nextToken(lexer.TokenKindPermission)
|
|
||||||
if err != nil { return }
|
|
||||||
member.permission = parser.token.Value().(types.Permission)
|
|
||||||
|
|
||||||
// get name
|
|
||||||
err = parser.nextToken(lexer.TokenKindName)
|
|
||||||
if err != nil { return }
|
|
||||||
member.name = parser.token.Value().(string)
|
|
||||||
|
|
||||||
// get type
|
|
||||||
err = parser.nextToken(lexer.TokenKindColon)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
member.what, err = parser.parseType()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
// if there is a bit width, get it
|
|
||||||
if parser.token.Is(lexer.TokenKindBinaryAnd) {
|
|
||||||
err = parser.nextToken(lexer.TokenKindUInt)
|
|
||||||
if err != nil { return }
|
|
||||||
member.bitWidth = parser.token.Value().(uint64)
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse default value
|
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
member.value,
|
|
||||||
err = parser.parseInitializationValues(1)
|
|
||||||
if err != nil { return }
|
|
||||||
} else {
|
|
||||||
member.value, err = parser.parseArgument()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
err = parser.expect(lexer.TokenKindNewline)
|
|
||||||
if err != nil { return }
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package parser
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestObjt (test *testing.T) {
|
|
||||||
checkTree ("../tests/parser/objt", false,
|
|
||||||
`:arf
|
|
||||||
---
|
|
||||||
objt ro Basic:Obj
|
|
||||||
ro that:Basic
|
|
||||||
ro this:Basic
|
|
||||||
objt ro BitFields:Obj
|
|
||||||
ro that:Int & 1
|
|
||||||
ro this:Int & 24 298
|
|
||||||
objt ro ComplexInit:Obj
|
|
||||||
ro whatever:Int:3
|
|
||||||
230984
|
|
||||||
849
|
|
||||||
394580
|
|
||||||
ro complex0:Bird
|
|
||||||
.that 98
|
|
||||||
.this 2
|
|
||||||
ro complex1:Bird
|
|
||||||
.that 98902
|
|
||||||
.this 235
|
|
||||||
ro basic:Int 87
|
|
||||||
objt ro Init:Obj
|
|
||||||
ro that:String "hello world"
|
|
||||||
ro this:Int 23
|
|
||||||
`, test)
|
|
||||||
}
|
|
@ -166,3 +166,21 @@ func (parser *ParsingOperation) skipIndentLevel (indent int) (err error) {
|
|||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skipWhitespace skips over newlines and indent tokens.
|
||||||
|
func (parser *ParsingOperation) skipWhitespace () (err error) {
|
||||||
|
for {
|
||||||
|
isWhitespace :=
|
||||||
|
parser.token.Is(lexer.TokenKindIndent) ||
|
||||||
|
parser.token.Is(lexer.TokenKindNewline)
|
||||||
|
|
||||||
|
if !isWhitespace {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -139,25 +139,16 @@ func (parser *ParsingOperation) parseBlockLevelPhrase (
|
|||||||
err = parser.expect(validDelimitedPhraseTokens...)
|
err = parser.expect(validDelimitedPhraseTokens...)
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
|
// we are delimited so we can safely skip whitespace
|
||||||
|
err = parser.skipWhitespace()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
if parser.token.Is(lexer.TokenKindRBracket) {
|
if parser.token.Is(lexer.TokenKindRBracket) {
|
||||||
// this is an ending delimiter
|
// this is an ending delimiter
|
||||||
err = parser.nextToken()
|
err = parser.nextToken()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
break
|
break
|
||||||
|
|
||||||
} else if parser.token.Is(lexer.TokenKindNewline) {
|
|
||||||
// we are delimited, so we can safely skip
|
|
||||||
// newlines
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
continue
|
|
||||||
|
|
||||||
} else if parser.token.Is(lexer.TokenKindIndent) {
|
|
||||||
// we are delimited, so we can safely skip
|
|
||||||
// indents
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not delimited
|
// not delimited
|
||||||
@ -176,7 +167,7 @@ func (parser *ParsingOperation) parseBlockLevelPhrase (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is an argument
|
// if we've got this far, we are parsing an argument
|
||||||
var argument Argument
|
var argument Argument
|
||||||
argument, err = parser.parseArgument()
|
argument, err = parser.parseArgument()
|
||||||
phrase.arguments = append(phrase.arguments, argument)
|
phrase.arguments = append(phrase.arguments, argument)
|
||||||
@ -213,18 +204,6 @@ func (parser *ParsingOperation) parseBlockLevelPhrase (
|
|||||||
err = parser.nextToken()
|
err = parser.nextToken()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
// if this is a set phrase, parse initialization values under it
|
|
||||||
if phrase.kind == PhraseKindAssign {
|
|
||||||
var values Argument
|
|
||||||
values, err = parser.parseInitializationValues(indent)
|
|
||||||
|
|
||||||
if values.kind != ArgumentKindNil {
|
|
||||||
phrase.arguments = append(phrase.arguments, values)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this is a control flow phrase, parse block under it
|
// if this is a control flow phrase, parse block under it
|
||||||
isControlFlow := false
|
isControlFlow := false
|
||||||
for _, kind := range controlFlowKinds {
|
for _, kind := range controlFlowKinds {
|
||||||
@ -234,10 +213,9 @@ func (parser *ParsingOperation) parseBlockLevelPhrase (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isControlFlow { return }
|
if isControlFlow {
|
||||||
|
|
||||||
// if it is any of those, parse the block under it
|
|
||||||
phrase.block, err = parser.parseBlock(indent + 1)
|
phrase.block, err = parser.parseBlock(indent + 1)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -330,6 +308,8 @@ func (parser *ParsingOperation) parsePhraseCommand () (
|
|||||||
identifier := command.value.(Identifier)
|
identifier := command.value.(Identifier)
|
||||||
if len(identifier.trail) == 1 {
|
if len(identifier.trail) == 1 {
|
||||||
switch identifier.trail[0] {
|
switch identifier.trail[0] {
|
||||||
|
case "let":
|
||||||
|
kind = PhraseKindLet
|
||||||
case "loc":
|
case "loc":
|
||||||
kind = PhraseKindReference
|
kind = PhraseKindReference
|
||||||
case "defer":
|
case "defer":
|
||||||
|
@ -66,12 +66,84 @@ func (identifier Identifier) ToString () (output string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (what Type) ToString () (output string) {
|
func (values ObjectDefaultValues) ToString (
|
||||||
|
indent int,
|
||||||
|
breakLine bool,
|
||||||
|
) (
|
||||||
|
output string,
|
||||||
|
) {
|
||||||
|
if !breakLine { indent = 0 }
|
||||||
|
output += doIndent(indent, "(")
|
||||||
|
if breakLine { output += "\n" }
|
||||||
|
|
||||||
|
for index, name := range sortMapKeysAlphabetically(values) {
|
||||||
|
if index > 0 && !breakLine { output += " " }
|
||||||
|
|
||||||
|
value := values[name]
|
||||||
|
|
||||||
|
output += doIndent(indent, "." + name + ":")
|
||||||
|
|
||||||
|
isComplexDefaultValue :=
|
||||||
|
value.kind == ArgumentKindObjectDefaultValues ||
|
||||||
|
value.kind == ArgumentKindArrayDefaultValues
|
||||||
|
|
||||||
|
if isComplexDefaultValue {
|
||||||
|
if breakLine { output += "\n" }
|
||||||
|
output += value.ToString(indent + 1, breakLine)
|
||||||
|
} else {
|
||||||
|
output += "<"
|
||||||
|
output += value.ToString(indent + 1, false)
|
||||||
|
output += ">"
|
||||||
|
}
|
||||||
|
if breakLine { output += "\n" }
|
||||||
|
}
|
||||||
|
output += doIndent(indent, ")")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (values ArrayDefaultValues) ToString (
|
||||||
|
indent int,
|
||||||
|
breakLine bool,
|
||||||
|
) (
|
||||||
|
output string,
|
||||||
|
) {
|
||||||
|
if !breakLine { indent = 0 }
|
||||||
|
output += doIndent(indent, "<")
|
||||||
|
if breakLine { output += "\n" }
|
||||||
|
|
||||||
|
for index, value := range values {
|
||||||
|
if index > 0 && !breakLine { output += " " }
|
||||||
|
output += value.ToString(indent, breakLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
output += doIndent(indent, ">")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (member TypeMember) ToString (indent int, breakLine bool) (output string) {
|
||||||
|
output += doIndent(indent, ".")
|
||||||
|
|
||||||
|
output += member.permission.ToString() + " "
|
||||||
|
output += member.name + ":"
|
||||||
|
output += member.what.ToString(indent + 1, breakLine)
|
||||||
|
|
||||||
|
if member.bitWidth > 0 {
|
||||||
|
output += fmt.Sprint(" & ", member.bitWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if breakLine {
|
||||||
|
output += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (what Type) ToString (indent int, breakLine bool) (output string) {
|
||||||
if what.kind == TypeKindBasic {
|
if what.kind == TypeKindBasic {
|
||||||
output += what.name.ToString()
|
output += what.name.ToString()
|
||||||
} else {
|
} else {
|
||||||
output += "{"
|
output += "{"
|
||||||
output += what.points.ToString()
|
output += what.points.ToString(indent, breakLine)
|
||||||
|
|
||||||
if what.kind == TypeKindVariableArray {
|
if what.kind == TypeKindVariableArray {
|
||||||
output += " .."
|
output += " .."
|
||||||
@ -88,44 +160,45 @@ func (what Type) ToString () (output string) {
|
|||||||
output += ":mut"
|
output += ":mut"
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
if what.members != nil {
|
||||||
|
if breakLine {
|
||||||
|
output += ":\n" + doIndent(indent, "(\n")
|
||||||
|
for _, member := range what.members {
|
||||||
|
output += member.ToString(indent, breakLine)
|
||||||
}
|
}
|
||||||
|
output += doIndent(indent, ")")
|
||||||
func (declaration Declaration) ToString () (output string) {
|
|
||||||
output += declaration.name + ":"
|
|
||||||
output += declaration.what.ToString()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (attributes ObjectInitializationValues) ToString (
|
|
||||||
indent int,
|
|
||||||
) (
|
|
||||||
output string,
|
|
||||||
) {
|
|
||||||
for _, name := range sortMapKeysAlphabetically(attributes.attributes) {
|
|
||||||
value := attributes.attributes[name]
|
|
||||||
|
|
||||||
output += doIndent(indent, ".", name)
|
|
||||||
if value.kind == ArgumentKindObjectInitializationValues {
|
|
||||||
output += "\n"
|
|
||||||
output += value.ToString(indent + 1, true)
|
|
||||||
} else {
|
} else {
|
||||||
output += " " + value.ToString(0, false) + "\n"
|
output += ":("
|
||||||
|
for index, member := range what.members {
|
||||||
|
if index > 0 { output += " " }
|
||||||
|
output += member.ToString(indent, breakLine)
|
||||||
|
}
|
||||||
|
output += ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultValueKind := what.defaultValue.kind
|
||||||
|
if defaultValueKind != ArgumentKindNil {
|
||||||
|
isComplexDefaultValue :=
|
||||||
|
defaultValueKind == ArgumentKindObjectDefaultValues ||
|
||||||
|
defaultValueKind == ArgumentKindArrayDefaultValues
|
||||||
|
|
||||||
|
if isComplexDefaultValue {
|
||||||
|
output += ":"
|
||||||
|
if breakLine { output += "\n" }
|
||||||
|
output += what.defaultValue.ToString(indent, breakLine)
|
||||||
|
} else {
|
||||||
|
output += ":<"
|
||||||
|
output += what.defaultValue.ToString(indent, false)
|
||||||
|
output += ">"
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (values ArrayInitializationValues) ToString (
|
func (declaration Declaration) ToString (indent int) (output string) {
|
||||||
indent int,
|
output += declaration.name + ":"
|
||||||
) (
|
output += declaration.what.ToString(indent, false)
|
||||||
output string,
|
|
||||||
) {
|
|
||||||
for _, value := range values.values {
|
|
||||||
output += value.ToString(indent, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,15 +216,13 @@ func (argument Argument) ToString (indent int, breakLine bool) (output string) {
|
|||||||
indent,
|
indent,
|
||||||
breakLine)
|
breakLine)
|
||||||
|
|
||||||
case ArgumentKindObjectInitializationValues:
|
case ArgumentKindObjectDefaultValues:
|
||||||
// this should only appear in contexts where breakLine is true
|
output += argument.value.(ObjectDefaultValues).
|
||||||
output += argument.value.(ObjectInitializationValues).
|
ToString(indent, breakLine)
|
||||||
ToString(indent)
|
|
||||||
|
|
||||||
case ArgumentKindArrayInitializationValues:
|
case ArgumentKindArrayDefaultValues:
|
||||||
// this should only appear in contexts where breakLine is true
|
output += argument.value.(ArrayDefaultValues).
|
||||||
output += argument.value.(ArrayInitializationValues).
|
ToString(indent, breakLine)
|
||||||
ToString(indent)
|
|
||||||
|
|
||||||
case ArgumentKindIdentifier:
|
case ArgumentKindIdentifier:
|
||||||
output += doIndent (
|
output += doIndent (
|
||||||
@ -162,7 +233,7 @@ func (argument Argument) ToString (indent int, breakLine bool) (output string) {
|
|||||||
case ArgumentKindDeclaration:
|
case ArgumentKindDeclaration:
|
||||||
output += doIndent (
|
output += doIndent (
|
||||||
indent,
|
indent,
|
||||||
argument.value.(Declaration).ToString())
|
argument.value.(Declaration).ToString(indent))
|
||||||
if breakLine { output += "\n" }
|
if breakLine { output += "\n" }
|
||||||
|
|
||||||
case ArgumentKindInt, ArgumentKindUInt, ArgumentKindFloat:
|
case ArgumentKindInt, ArgumentKindUInt, ArgumentKindFloat:
|
||||||
@ -260,24 +331,12 @@ func (section DataSection) ToString (indent int) (output string) {
|
|||||||
"data ",
|
"data ",
|
||||||
section.permission.ToString(), " ",
|
section.permission.ToString(), " ",
|
||||||
section.name, ":",
|
section.name, ":",
|
||||||
section.what.ToString())
|
section.what.ToString(indent + 1, true), "\n")
|
||||||
|
|
||||||
isComplexInitialization :=
|
|
||||||
section.value.kind == ArgumentKindObjectInitializationValues ||
|
|
||||||
section.value.kind == ArgumentKindArrayInitializationValues
|
|
||||||
|
|
||||||
if section.external {
|
if section.external {
|
||||||
output += "\n"
|
|
||||||
output += doIndent(indent + 1, "external\n")
|
output += doIndent(indent + 1, "external\n")
|
||||||
} else if section.value.value == nil {
|
|
||||||
output += "\n"
|
|
||||||
} else if isComplexInitialization {
|
|
||||||
output += "\n"
|
|
||||||
output += section.value.ToString(indent + 1, true)
|
|
||||||
} else {
|
|
||||||
output += " " + section.value.ToString(0, false)
|
|
||||||
output += "\n"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,65 +346,10 @@ func (section TypeSection) ToString (indent int) (output string) {
|
|||||||
"type ",
|
"type ",
|
||||||
section.permission.ToString(), " ",
|
section.permission.ToString(), " ",
|
||||||
section.name, ":",
|
section.name, ":",
|
||||||
section.what.ToString())
|
section.what.ToString(indent + 1, true), "\n")
|
||||||
|
|
||||||
isComplexInitialization :=
|
|
||||||
section.value.kind == ArgumentKindObjectInitializationValues ||
|
|
||||||
section.value.kind == ArgumentKindArrayInitializationValues
|
|
||||||
|
|
||||||
if section.value.value == nil {
|
|
||||||
output += "\n"
|
|
||||||
} else if isComplexInitialization {
|
|
||||||
output += "\n"
|
|
||||||
output += section.value.ToString(indent + 1, true)
|
|
||||||
} else {
|
|
||||||
output += " " + section.value.ToString(0, false)
|
|
||||||
output += "\n"
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (member ObjtMember) ToString (indent int) (output string) {
|
|
||||||
output += doIndent(indent)
|
|
||||||
|
|
||||||
output += member.permission.ToString() + " "
|
|
||||||
output += member.name + ":"
|
|
||||||
output += member.what.ToString()
|
|
||||||
|
|
||||||
if member.bitWidth > 0 {
|
|
||||||
output += fmt.Sprint(" & ", member.bitWidth)
|
|
||||||
}
|
|
||||||
|
|
||||||
isComplexInitialization :=
|
|
||||||
member.value.kind == ArgumentKindObjectInitializationValues ||
|
|
||||||
member.value.kind == ArgumentKindArrayInitializationValues
|
|
||||||
|
|
||||||
if member.value.value == nil {
|
|
||||||
output += "\n"
|
|
||||||
} else if isComplexInitialization {
|
|
||||||
output += "\n"
|
|
||||||
output += member.value.ToString(indent + 1, true)
|
|
||||||
} else {
|
|
||||||
output += " " + member.value.ToString(0, false)
|
|
||||||
output += "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (section ObjtSection) ToString (indent int) (output string) {
|
|
||||||
output += doIndent (
|
|
||||||
indent,
|
|
||||||
"objt ",
|
|
||||||
section.permission.ToString(), " ",
|
|
||||||
section.name, ":",
|
|
||||||
section.inherits.ToString(), "\n")
|
|
||||||
|
|
||||||
for _, member := range section.members {
|
|
||||||
output += member.ToString(indent + 1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (section EnumSection) ToString (indent int) (output string) {
|
func (section EnumSection) ToString (indent int) (output string) {
|
||||||
output += doIndent (
|
output += doIndent (
|
||||||
@ -353,24 +357,22 @@ func (section EnumSection) ToString (indent int) (output string) {
|
|||||||
"enum ",
|
"enum ",
|
||||||
section.permission.ToString(), " ",
|
section.permission.ToString(), " ",
|
||||||
section.name, ":",
|
section.name, ":",
|
||||||
section.what.ToString(), "\n")
|
section.what.ToString(indent + 1, true), "\n")
|
||||||
|
|
||||||
for _, member := range section.members {
|
for _, member := range section.members {
|
||||||
output += doIndent(indent + 1, member.name)
|
output += doIndent(indent + 1, "- ", member.name)
|
||||||
|
|
||||||
isComplexInitialization :=
|
isComplexInitialization :=
|
||||||
member.value.kind == ArgumentKindObjectInitializationValues ||
|
member.value.kind == ArgumentKindObjectDefaultValues ||
|
||||||
member.value.kind == ArgumentKindArrayInitializationValues
|
member.value.kind == ArgumentKindArrayDefaultValues
|
||||||
|
|
||||||
if member.value.value == nil {
|
if isComplexInitialization {
|
||||||
output += "\n"
|
output += ":\n"
|
||||||
} else if isComplexInitialization {
|
|
||||||
output += "\n"
|
|
||||||
output += member.value.ToString(indent + 2, true)
|
output += member.value.ToString(indent + 2, true)
|
||||||
} else {
|
} else if member.value.kind != ArgumentKindNil {
|
||||||
output += " " + member.value.ToString(0, false)
|
output += ":<" + member.value.ToString(0, false) + ">"
|
||||||
output += "\n"
|
|
||||||
}
|
}
|
||||||
|
output += "\n"
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -394,11 +396,11 @@ func (behavior FaceBehavior) ToString (indent int) (output string) {
|
|||||||
output += doIndent(indent, behavior.name, "\n")
|
output += doIndent(indent, behavior.name, "\n")
|
||||||
|
|
||||||
for _, inputItem := range behavior.inputs {
|
for _, inputItem := range behavior.inputs {
|
||||||
output += doIndent(indent + 1, "> ", inputItem.ToString(), "\n")
|
output += doIndent(indent + 1, "> ", inputItem.ToString(indent), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, outputItem := range behavior.outputs {
|
for _, outputItem := range behavior.outputs {
|
||||||
output += doIndent(indent + 1, "< ", outputItem.ToString(), "\n")
|
output += doIndent(indent + 1, "< ", outputItem.ToString(indent), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -409,19 +411,10 @@ func (phrase Phrase) ToString (indent int, ownLine bool) (output string) {
|
|||||||
output += doIndent(indent)
|
output += doIndent(indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
var initializationValues Argument
|
|
||||||
|
|
||||||
output += "[" + phrase.command.ToString(0, false)
|
output += "[" + phrase.command.ToString(0, false)
|
||||||
for _, argument := range phrase.arguments {
|
for _, argument := range phrase.arguments {
|
||||||
isInitializationValue :=
|
|
||||||
argument.kind == ArgumentKindObjectInitializationValues ||
|
|
||||||
argument.kind == ArgumentKindArrayInitializationValues
|
|
||||||
if isInitializationValue {
|
|
||||||
initializationValues = argument
|
|
||||||
} else {
|
|
||||||
output += " " + argument.ToString(0, false)
|
output += " " + argument.ToString(0, false)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
output += "]"
|
output += "]"
|
||||||
|
|
||||||
if len(phrase.returnees) > 0 {
|
if len(phrase.returnees) > 0 {
|
||||||
@ -433,10 +426,9 @@ func (phrase Phrase) ToString (indent int, ownLine bool) (output string) {
|
|||||||
|
|
||||||
if ownLine {
|
if ownLine {
|
||||||
output += "\n"
|
output += "\n"
|
||||||
if initializationValues.kind != ArgumentKindNil {
|
|
||||||
output += initializationValues.ToString(indent + 1, true)
|
|
||||||
}
|
|
||||||
output += phrase.block.ToString(indent + 1)
|
output += phrase.block.ToString(indent + 1)
|
||||||
|
} else if len(phrase.block) > 0 {
|
||||||
|
output += "NON-BLOCK-LEVEL-PHRASE-HAS-BLOCK"
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -449,14 +441,6 @@ func (block Block) ToString (indent int) (output string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (funcOutput FuncOutput) ToString () (output string) {
|
|
||||||
output += funcOutput.Declaration.ToString()
|
|
||||||
if funcOutput.value.kind != ArgumentKindNil {
|
|
||||||
output += " " + funcOutput.value.ToString(0, false)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (section FuncSection) ToString (indent int) (output string) {
|
func (section FuncSection) ToString (indent int) (output string) {
|
||||||
output += doIndent (
|
output += doIndent (
|
||||||
indent,
|
indent,
|
||||||
@ -467,15 +451,15 @@ func (section FuncSection) ToString (indent int) (output string) {
|
|||||||
if section.receiver != nil {
|
if section.receiver != nil {
|
||||||
output += doIndent (
|
output += doIndent (
|
||||||
indent + 1,
|
indent + 1,
|
||||||
"@ ", section.receiver.ToString(), "\n")
|
"@ ", section.receiver.ToString(indent), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, inputItem := range section.inputs {
|
for _, inputItem := range section.inputs {
|
||||||
output += doIndent(indent + 1, "> ", inputItem.ToString(), "\n")
|
output += doIndent(indent + 1, "> ", inputItem.ToString(indent), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, outputItem := range section.outputs {
|
for _, outputItem := range section.outputs {
|
||||||
output += doIndent(indent + 1, "< ", outputItem.ToString(), "\n")
|
output += doIndent(indent + 1, "< ", outputItem.ToString(indent), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
output += doIndent(indent + 1, "---\n")
|
output += doIndent(indent + 1, "---\n")
|
||||||
|
@ -20,7 +20,6 @@ type SectionKind int
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
SectionKindType = iota
|
SectionKindType = iota
|
||||||
SectionKindObjt
|
|
||||||
SectionKindEnum
|
SectionKindEnum
|
||||||
SectionKindFace
|
SectionKindFace
|
||||||
SectionKindData
|
SectionKindData
|
||||||
@ -48,17 +47,27 @@ type Identifier struct {
|
|||||||
type TypeKind int
|
type TypeKind int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TypeKindBasic either means it's a primitive, or it inherits from
|
// TypeKindBasic means its a normal type and inherits from something.
|
||||||
// something.
|
// Basic types can define new members on their parent types.
|
||||||
TypeKindBasic TypeKind = iota
|
TypeKindBasic TypeKind = iota
|
||||||
|
|
||||||
// TypeKindPointer means it's a pointer
|
// TypeKindPointer means it's a pointer.
|
||||||
TypeKindPointer
|
TypeKindPointer
|
||||||
|
|
||||||
// TypeKindVariableArray means it's an array of variable length.
|
// TypeKindVariableArray means it's an array of variable length.
|
||||||
TypeKindVariableArray
|
TypeKindVariableArray
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TypeMember represents a member variable of a type specifier.
|
||||||
|
type TypeMember struct {
|
||||||
|
locatable
|
||||||
|
nameable
|
||||||
|
typeable
|
||||||
|
permissionable
|
||||||
|
|
||||||
|
bitWidth uint64
|
||||||
|
}
|
||||||
|
|
||||||
// Type represents a type specifier
|
// Type represents a type specifier
|
||||||
type Type struct {
|
type Type struct {
|
||||||
locatable
|
locatable
|
||||||
@ -72,6 +81,12 @@ type Type struct {
|
|||||||
|
|
||||||
// not applicable for basic.
|
// not applicable for basic.
|
||||||
points *Type
|
points *Type
|
||||||
|
|
||||||
|
// if non-nil, this type defines new members.
|
||||||
|
members []TypeMember
|
||||||
|
|
||||||
|
// the default value of the type.
|
||||||
|
defaultValue Argument
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declaration represents a variable declaration.
|
// Declaration represents a variable declaration.
|
||||||
@ -81,19 +96,12 @@ type Declaration struct {
|
|||||||
typeable
|
typeable
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectInitializationValues represents a list of object member initialization
|
// ObjectDefaultValues represents a list of object member initialization
|
||||||
// attributes.
|
// attributes.
|
||||||
type ObjectInitializationValues struct {
|
type ObjectDefaultValues map[string] Argument
|
||||||
locatable
|
|
||||||
attributes map[string] Argument
|
|
||||||
}
|
|
||||||
|
|
||||||
// ArrayInitializationValues represents a list of attributes initializing an
|
// ArrayDefaultValues represents a list of elements initializing an array.
|
||||||
// array.
|
type ArrayDefaultValues []Argument
|
||||||
type ArrayInitializationValues struct {
|
|
||||||
locatable
|
|
||||||
values []Argument
|
|
||||||
}
|
|
||||||
|
|
||||||
// ArgumentKind specifies the type of thing the value of an argument should be
|
// ArgumentKind specifies the type of thing the value of an argument should be
|
||||||
// cast to.
|
// cast to.
|
||||||
@ -113,12 +121,12 @@ const (
|
|||||||
// {name 23}
|
// {name 23}
|
||||||
ArgumentKindSubscript
|
ArgumentKindSubscript
|
||||||
|
|
||||||
// .name value
|
// (.name <value>)
|
||||||
// but like, a lot of them
|
// (.name <value> .name (.name <value))
|
||||||
ArgumentKindObjectInitializationValues
|
ArgumentKindObjectDefaultValues
|
||||||
|
|
||||||
// value value...
|
// <4 32 98 5>
|
||||||
ArgumentKindArrayInitializationValues
|
ArgumentKindArrayDefaultValues
|
||||||
|
|
||||||
// name.name
|
// name.name
|
||||||
// name.name.name
|
// name.name.name
|
||||||
@ -168,39 +176,16 @@ type DataSection struct {
|
|||||||
nameable
|
nameable
|
||||||
typeable
|
typeable
|
||||||
permissionable
|
permissionable
|
||||||
valuable
|
|
||||||
|
|
||||||
external bool
|
external bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypeSection represents a blind type definition.
|
// TypeSection represents a type definition.
|
||||||
type TypeSection struct {
|
type TypeSection struct {
|
||||||
locatable
|
locatable
|
||||||
nameable
|
nameable
|
||||||
typeable
|
typeable
|
||||||
permissionable
|
permissionable
|
||||||
valuable
|
|
||||||
}
|
|
||||||
|
|
||||||
// ObjtMember represents a part of an object type definition.
|
|
||||||
type ObjtMember struct {
|
|
||||||
locatable
|
|
||||||
nameable
|
|
||||||
typeable
|
|
||||||
permissionable
|
|
||||||
valuable
|
|
||||||
|
|
||||||
bitWidth uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// ObjtSection represents an object type definition.
|
|
||||||
type ObjtSection struct {
|
|
||||||
locatable
|
|
||||||
nameable
|
|
||||||
permissionable
|
|
||||||
inherits Identifier
|
|
||||||
|
|
||||||
members []ObjtMember
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnumMember represents a member of an enum section.
|
// EnumMember represents a member of an enum section.
|
||||||
@ -246,6 +231,7 @@ const (
|
|||||||
PhraseKindCall = iota
|
PhraseKindCall = iota
|
||||||
PhraseKindCallExternal
|
PhraseKindCallExternal
|
||||||
PhraseKindOperator
|
PhraseKindOperator
|
||||||
|
PhraseKindLet
|
||||||
PhraseKindAssign
|
PhraseKindAssign
|
||||||
PhraseKindReference
|
PhraseKindReference
|
||||||
PhraseKindDefer
|
PhraseKindDefer
|
||||||
@ -275,13 +261,6 @@ type Phrase struct {
|
|||||||
// Block represents a scoped/indented block of code.
|
// Block represents a scoped/indented block of code.
|
||||||
type Block []Phrase
|
type Block []Phrase
|
||||||
|
|
||||||
// FuncOutput represents an input a function section. It is unlike an input in
|
|
||||||
// that it can have a default value.
|
|
||||||
type FuncOutput struct {
|
|
||||||
Declaration
|
|
||||||
valuable
|
|
||||||
}
|
|
||||||
|
|
||||||
// FuncSection represents a function section.
|
// FuncSection represents a function section.
|
||||||
type FuncSection struct {
|
type FuncSection struct {
|
||||||
locatable
|
locatable
|
||||||
@ -290,7 +269,7 @@ type FuncSection struct {
|
|||||||
|
|
||||||
receiver *Declaration
|
receiver *Declaration
|
||||||
inputs []Declaration
|
inputs []Declaration
|
||||||
outputs []FuncOutput
|
outputs []Declaration
|
||||||
root Block
|
root Block
|
||||||
|
|
||||||
external bool
|
external bool
|
||||||
|
318
parser/type-notation.go
Normal file
318
parser/type-notation.go
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
package parser
|
||||||
|
|
||||||
|
import "git.tebibyte.media/arf/arf/lexer"
|
||||||
|
import "git.tebibyte.media/arf/arf/infoerr"
|
||||||
|
import "git.tebibyte.media/arf/arf/types"
|
||||||
|
|
||||||
|
// parseType parses a type notation of the form Name, {Name}, etc.
|
||||||
|
func (parser *ParsingOperation) parseType () (what Type, err error) {
|
||||||
|
err = parser.expect(lexer.TokenKindName, lexer.TokenKindLBrace)
|
||||||
|
if err != nil { return }
|
||||||
|
what.location = parser.token.Location()
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindLBrace) {
|
||||||
|
what.kind = TypeKindPointer
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
var points Type
|
||||||
|
points, err = parser.parseType()
|
||||||
|
if err != nil { return }
|
||||||
|
what.points = &points
|
||||||
|
|
||||||
|
err = parser.expect (
|
||||||
|
lexer.TokenKindRBrace,
|
||||||
|
lexer.TokenKindElipsis)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindElipsis) {
|
||||||
|
what.kind = TypeKindVariableArray
|
||||||
|
|
||||||
|
err = parser.nextToken(lexer.TokenKindRBrace)
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
} else {
|
||||||
|
what.name, err = parser.parseIdentifier()
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if !parser.token.Is(lexer.TokenKindColon) { break }
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
err = parser.skipWhitespace()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
err = parser.expect(
|
||||||
|
lexer.TokenKindName,
|
||||||
|
lexer.TokenKindUInt,
|
||||||
|
lexer.TokenKindLParen,
|
||||||
|
lexer.TokenKindLessThan)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindName) {
|
||||||
|
// parse type qualifier
|
||||||
|
qualifier := parser.token.Value().(string)
|
||||||
|
switch qualifier {
|
||||||
|
case "mut":
|
||||||
|
what.mutable = true
|
||||||
|
default:
|
||||||
|
err = parser.token.NewError (
|
||||||
|
"unknown type qualifier \"" +
|
||||||
|
qualifier + "\"",
|
||||||
|
infoerr.ErrorKindError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
} else if parser.token.Is(lexer.TokenKindUInt) {
|
||||||
|
// parse fixed array length
|
||||||
|
what.length = parser.token.Value().(uint64)
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
} else if parser.token.Is(lexer.TokenKindLessThan) {
|
||||||
|
// parse default value
|
||||||
|
what.defaultValue, err = parser.parseBasicDefaultValue()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
} else if parser.token.Is(lexer.TokenKindLParen) {
|
||||||
|
// parse members and member default values
|
||||||
|
what.defaultValue,
|
||||||
|
what.members,
|
||||||
|
err = parser.parseObjectDefaultValueAndMembers()
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseBasicDefaultValue parses a default value of a non-object type.
|
||||||
|
func (parser *ParsingOperation) parseBasicDefaultValue () (
|
||||||
|
value Argument,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
value.location = parser.token.Location()
|
||||||
|
|
||||||
|
err = parser.expect(lexer.TokenKindLessThan)
|
||||||
|
if err != nil { return }
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
var attributes []Argument
|
||||||
|
|
||||||
|
defer func () {
|
||||||
|
// if we have multiple values, we need to return the full array
|
||||||
|
// instead.
|
||||||
|
if len(attributes) > 1 {
|
||||||
|
value.kind = ArgumentKindArrayDefaultValues
|
||||||
|
value.value = ArrayDefaultValues(attributes)
|
||||||
|
}
|
||||||
|
} ()
|
||||||
|
|
||||||
|
for {
|
||||||
|
err = parser.skipWhitespace()
|
||||||
|
if err != nil { return }
|
||||||
|
if parser.token.Is(lexer.TokenKindGreaterThan) { break }
|
||||||
|
|
||||||
|
value, err = parser.parseArgument()
|
||||||
|
if err != nil { return }
|
||||||
|
attributes = append(attributes, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseObjectDefaultValueAndMembers parses default values and new members of an
|
||||||
|
// object type.
|
||||||
|
func (parser *ParsingOperation) parseObjectDefaultValueAndMembers () (
|
||||||
|
value Argument,
|
||||||
|
members []TypeMember,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
value.location = parser.token.Location()
|
||||||
|
|
||||||
|
err = parser.expect(lexer.TokenKindLParen)
|
||||||
|
if err != nil { return }
|
||||||
|
parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
var attributes ObjectDefaultValues
|
||||||
|
|
||||||
|
for {
|
||||||
|
err = parser.skipWhitespace()
|
||||||
|
if err != nil { return }
|
||||||
|
if parser.token.Is(lexer.TokenKindRParen) { break }
|
||||||
|
|
||||||
|
err = parser.expect(lexer.TokenKindDot)
|
||||||
|
if err != nil { return }
|
||||||
|
parser.nextToken(lexer.TokenKindName, lexer.TokenKindPermission)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindName) {
|
||||||
|
// parsing a defalut value for an inherited member
|
||||||
|
var memberName string
|
||||||
|
var memberValue Argument
|
||||||
|
|
||||||
|
memberName,
|
||||||
|
memberValue, err = parser.parseObjectInheritedMember()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if value.kind == ArgumentKindNil {
|
||||||
|
// create default value map if it doesn't
|
||||||
|
// already exist
|
||||||
|
value.kind = ArgumentKindObjectDefaultValues
|
||||||
|
attributes = make(ObjectDefaultValues)
|
||||||
|
value.value = attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: error on duplicate
|
||||||
|
if memberValue.kind != ArgumentKindNil {
|
||||||
|
attributes[memberName] = memberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if parser.token.Is(lexer.TokenKindPermission) {
|
||||||
|
// parsing a member declaration
|
||||||
|
var member TypeMember
|
||||||
|
member, err = parser.parseObjectNewMember()
|
||||||
|
|
||||||
|
// TODO: error on duplicate
|
||||||
|
members = append(members, member)
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseObjectDefaultValue parses member default values only, and will throw an
|
||||||
|
// error when it encounteres a new member definition.
|
||||||
|
func (parser *ParsingOperation) parseObjectDefaultValue () (
|
||||||
|
value Argument,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
value.location = parser.token.Location()
|
||||||
|
|
||||||
|
err = parser.expect(lexer.TokenKindLParen)
|
||||||
|
if err != nil { return }
|
||||||
|
parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
var attributes ObjectDefaultValues
|
||||||
|
|
||||||
|
for {
|
||||||
|
err = parser.skipWhitespace()
|
||||||
|
if err != nil { return }
|
||||||
|
if parser.token.Is(lexer.TokenKindRParen) { break }
|
||||||
|
|
||||||
|
err = parser.expect(lexer.TokenKindDot)
|
||||||
|
if err != nil { return }
|
||||||
|
parser.nextToken(lexer.TokenKindName)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if value.kind == ArgumentKindNil {
|
||||||
|
value.kind = ArgumentKindObjectDefaultValues
|
||||||
|
attributes = make(ObjectDefaultValues)
|
||||||
|
value.value = attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
var memberName string
|
||||||
|
var memberValue Argument
|
||||||
|
memberName,
|
||||||
|
memberValue, err = parser.parseObjectInheritedMember()
|
||||||
|
|
||||||
|
attributes[memberName] = memberValue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// .name:<value>
|
||||||
|
|
||||||
|
// parseObjectInheritedMember parses a new default value for an inherited
|
||||||
|
// member.
|
||||||
|
func (parser *ParsingOperation) parseObjectInheritedMember () (
|
||||||
|
name string,
|
||||||
|
value Argument,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
// get the name of the inherited member
|
||||||
|
err = parser.expect(lexer.TokenKindName)
|
||||||
|
value.location = parser.token.Location()
|
||||||
|
if err != nil { return }
|
||||||
|
name = parser.token.Value().(string)
|
||||||
|
|
||||||
|
// we require a default value to be present
|
||||||
|
err = parser.nextToken(lexer.TokenKindColon)
|
||||||
|
if err != nil { return }
|
||||||
|
err = parser.nextToken(lexer.TokenKindLParen, lexer.TokenKindLessThan)
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
if parser.token.Is(lexer.TokenKindLessThan) {
|
||||||
|
// parse default value
|
||||||
|
value, err = parser.parseBasicDefaultValue()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
} else if parser.token.Is(lexer.TokenKindLParen) {
|
||||||
|
// parse member default values
|
||||||
|
value, err = parser.parseObjectDefaultValue()
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// .ro name:Type:qualifier:<value>
|
||||||
|
|
||||||
|
// parseObjectNewMember parses an object member declaration, and its
|
||||||
|
// default value if it exists.
|
||||||
|
func (parser *ParsingOperation) parseObjectNewMember () (
|
||||||
|
member TypeMember,
|
||||||
|
err error,
|
||||||
|
) {
|
||||||
|
// get member permission
|
||||||
|
err = parser.expect(lexer.TokenKindPermission)
|
||||||
|
member.location = parser.token.Location()
|
||||||
|
if err != nil { return }
|
||||||
|
member.permission = parser.token.Value().(types.Permission)
|
||||||
|
|
||||||
|
// get member name
|
||||||
|
err = parser.nextToken(lexer.TokenKindName)
|
||||||
|
if err != nil { return }
|
||||||
|
member.name = parser.token.Value().(string)
|
||||||
|
|
||||||
|
// get type
|
||||||
|
err = parser.nextToken(lexer.TokenKindColon)
|
||||||
|
if err != nil { return }
|
||||||
|
err = parser.nextToken(lexer.TokenKindName, lexer.TokenKindLBrace)
|
||||||
|
if err != nil { return }
|
||||||
|
member.what, err = parser.parseType()
|
||||||
|
if err != nil { return }
|
||||||
|
|
||||||
|
// get bit width
|
||||||
|
if parser.token.Is(lexer.TokenKindBinaryAnd) {
|
||||||
|
err = parser.nextToken(lexer.TokenKindUInt)
|
||||||
|
if err != nil { return }
|
||||||
|
member.bitWidth = parser.token.Value().(uint64)
|
||||||
|
err = parser.nextToken()
|
||||||
|
if err != nil { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
@ -32,21 +32,10 @@ func (parser *ParsingOperation) parseTypeSection () (
|
|||||||
section.what, err = parser.parseType()
|
section.what, err = parser.parseType()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
// parse default values
|
parser.expect(lexer.TokenKindNewline)
|
||||||
if parser.token.Is(lexer.TokenKindNewline) {
|
|
||||||
err = parser.nextToken()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
section.value, err = parser.parseInitializationValues(0)
|
|
||||||
if err != nil { return }
|
|
||||||
} else {
|
|
||||||
section.value, err = parser.parseArgument()
|
|
||||||
if err != nil { return }
|
|
||||||
|
|
||||||
err = parser.expect(lexer.TokenKindNewline)
|
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
err = parser.nextToken()
|
err = parser.nextToken()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,55 @@ func TestType (test *testing.T) {
|
|||||||
checkTree ("../tests/parser/type", false,
|
checkTree ("../tests/parser/type", false,
|
||||||
`:arf
|
`:arf
|
||||||
---
|
---
|
||||||
type ro Basic:Int
|
type ro aBasic:Obj:
|
||||||
type ro BasicInit:Int 6
|
(
|
||||||
type ro IntArray:{Int ..}
|
.ro that:Int
|
||||||
type ro IntArrayInit:Int:3
|
.ro this:Int
|
||||||
|
)
|
||||||
|
type ro bBitFields:Obj:
|
||||||
|
(
|
||||||
|
.ro that:Int & 1
|
||||||
|
.ro this:Int:<298> & 24
|
||||||
|
)
|
||||||
|
type ro cInit:Obj:
|
||||||
|
(
|
||||||
|
.ro that:String:<"hello world">
|
||||||
|
.ro this:Int:<23>
|
||||||
|
)
|
||||||
|
type ro dInitInherit:aBasic:
|
||||||
|
(
|
||||||
|
.that:<9384>
|
||||||
|
.this:<389>
|
||||||
|
)
|
||||||
|
type ro eInitAndDefine:aBasic:
|
||||||
|
(
|
||||||
|
.ro these:aBasic:
|
||||||
|
(
|
||||||
|
.ro born:Int:<4>
|
||||||
|
.ro in:Int
|
||||||
|
.ro the:Int:3:
|
||||||
|
<
|
||||||
|
9348
|
||||||
|
92384
|
||||||
|
92834
|
||||||
|
>
|
||||||
|
):
|
||||||
|
(
|
||||||
|
.this:<98>
|
||||||
|
)
|
||||||
|
):
|
||||||
|
(
|
||||||
|
.that:<9384>
|
||||||
|
.this:<389>
|
||||||
|
)
|
||||||
|
type ro fBasic:Int
|
||||||
|
type ro gBasicInit:Int:<6>
|
||||||
|
type ro hIntArray:{Int ..}
|
||||||
|
type ro iIntArrayInit:Int:3:
|
||||||
|
<
|
||||||
3298
|
3298
|
||||||
923
|
923
|
||||||
92
|
92
|
||||||
|
>
|
||||||
`, test)
|
`, test)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
:arf
|
:arf
|
||||||
--- rw -> -349820394 932748397 239485.37520 "hello world!\n" 'E' helloWorld:.,..[]{}
|
--- rw -> -349820394 932748397 239485.37520 "hello world!\n" 'E' helloWorld:.,..()[]{}
|
||||||
+ - ++ -- * / @ ! % %= ~ ~= = == != < <= << <<= > >= >> >>= | |= || & &= && ^ ^=
|
+ - ++ -- * / @ ! % %= ~ ~= = == != < <= << <<= > >= >> >>= | |= || & &= && ^ ^=
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
:arf
|
:arf
|
||||||
---
|
---
|
||||||
|
|
||||||
data ro aInteger:Int 3202
|
data ro aInteger:Int:<3202>
|
||||||
|
|
||||||
data ro bMutInteger:Int:mut 3202
|
data ro bMutInteger:Int:mut:<3202>
|
||||||
|
|
||||||
data ro cIntegerPointer:{Int}
|
data ro cIntegerPointer:{Int}
|
||||||
|
|
||||||
@ -13,34 +13,33 @@ data ro eIntegerArray16:Int:16
|
|||||||
|
|
||||||
data ro fIntegerArrayVariable:{Int ..}
|
data ro fIntegerArrayVariable:{Int ..}
|
||||||
|
|
||||||
data ro gIntegerArrayInitialized:Int:16
|
data ro gIntegerArrayInitialized:Int:16:<
|
||||||
3948 293 293049 948 912
|
3948 293 293049 948 912
|
||||||
340 0 2304 0 4785 92
|
340 0 2304 0 4785 92
|
||||||
|
>
|
||||||
|
|
||||||
# TODO: reinstate these two after phrase parsing is implemented
|
data rw hIntegerPointerInit:{Int}:<[& integer]>
|
||||||
# data wr hIntegerPointerInit:{Int} [& integer]
|
|
||||||
|
|
||||||
# data wr iMutIntegerPointerInit:{Int}:mut [& integer]
|
data rw iMutIntegerPointerInit:{Int}:mut:<[& integer]>
|
||||||
|
|
||||||
# TODO: maybe test identifiers somewhere else?
|
data ro jObject:Obj:(
|
||||||
data ro jObject:thing.Thing.
|
.this:<324>
|
||||||
thing.thing
|
.that:<324>)
|
||||||
.this 324
|
|
||||||
.that 2139
|
|
||||||
|
|
||||||
data ro kNestedObject:Obj
|
data ro kNestedObject:Obj:(
|
||||||
.this
|
.this:(
|
||||||
.bird0 324
|
.bird0:<324>
|
||||||
.bird1 "hello world"
|
.bird1:<"hello world">)
|
||||||
.that
|
.ro newMember:Int:<9023>
|
||||||
.bird2 123.8439
|
.that:(
|
||||||
.bird3 9328.21348239
|
.bird2:<123.8439>
|
||||||
|
.bird3:<9328.21348239>))
|
||||||
|
|
||||||
data ro lMutIntegerArray16:Int:16:mut
|
data ro lMutIntegerArray16:Int:16:mut
|
||||||
|
|
||||||
data ro mExternalData:Int:8
|
data ro mExternalData:Int:8
|
||||||
external
|
external
|
||||||
|
|
||||||
data ro nIntegerArrayInitialized:Int:16:mut
|
data ro nIntegerArrayInitialized:Int:16:mut:
|
||||||
3948 293 293049 948 912
|
<3948 293 293049 948 912
|
||||||
340 0 2304 0 4785 92
|
340 0 2304 0 4785 92>
|
||||||
|
@ -2,29 +2,35 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
enum ro Weekday:Int
|
enum ro Weekday:Int
|
||||||
sunday
|
- sunday
|
||||||
monday
|
- monday
|
||||||
tuesday
|
- tuesday
|
||||||
wednesday
|
- wednesday
|
||||||
thursday
|
- thursday
|
||||||
friday
|
- friday
|
||||||
saturday
|
- saturday
|
||||||
|
|
||||||
enum ro NamedColor:U32
|
enum ro NamedColor:U32
|
||||||
red 0xFF0000
|
- red: <0xFF0000>
|
||||||
green 0x00FF00
|
- green: <0x00FF00>
|
||||||
blue 0x0000FF
|
- blue: <0x0000FF>
|
||||||
|
|
||||||
enum ro AffrontToGod:Int:4
|
enum ro AffrontToGod:Int:4
|
||||||
bird0
|
- bird0:
|
||||||
28394 9328
|
<28394 9328
|
||||||
398 9
|
398 9>
|
||||||
bird1
|
- bird1:
|
||||||
23 932832
|
<23 932832
|
||||||
398
|
398
|
||||||
2349
|
2349>
|
||||||
bird2
|
- bird2:
|
||||||
1
|
<1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
4
|
4>
|
||||||
|
|
||||||
|
enum ro ThisIsTerrible:Obj:(.rw x:Int .rw y:Int)
|
||||||
|
- up: (.x:< 0> .y:<-1>)
|
||||||
|
- down: (.x:< 0> .y:< 1>)
|
||||||
|
- left: (.x:<-1> .y:< 0>)
|
||||||
|
- right: (.x:< 1> .y:< 0>)
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
---
|
---
|
||||||
func ro aBasicExternal
|
func ro aBasicExternal
|
||||||
> someInput:Int:mut
|
> someInput:Int:mut
|
||||||
< someOutput:Int 4
|
< someOutput:Int:<4>
|
||||||
---
|
---
|
||||||
external
|
external
|
||||||
|
|
||||||
func ro bMethod
|
func ro bMethod
|
||||||
@ bird:{Bird}
|
@ bird:{Bird}
|
||||||
> someInput:Int:mut
|
> someInput:Int:mut
|
||||||
< someOutput:Int 4
|
< someOutput:Int:<4>
|
||||||
---
|
---
|
||||||
external
|
external
|
||||||
|
|
||||||
@ -124,13 +124,12 @@ func ro gControlFlow
|
|||||||
|
|
||||||
func ro hSetPhrase
|
func ro hSetPhrase
|
||||||
---
|
---
|
||||||
= x:Int 3
|
let x:Int:<3>
|
||||||
# loc is a reference, similar to * in C
|
# loc is a reference, similar to * in C
|
||||||
= y:{Int} [loc x]
|
let y:{Int}:<[loc x]>
|
||||||
= z:Int:8
|
let z:Int:8:
|
||||||
398 9 2309 983 -2387
|
<398 9 2309 983 -2387
|
||||||
478 555 123
|
478 555 123>
|
||||||
= bird:Bird
|
let bird:Bird:(
|
||||||
.that
|
.that:(.whenYou:<99999>)
|
||||||
.whenYou 99999
|
.this:<324>)
|
||||||
.this 324
|
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
:arf
|
|
||||||
---
|
|
||||||
objt ro Basic:Obj
|
|
||||||
ro that:Basic
|
|
||||||
ro this:Basic
|
|
||||||
|
|
||||||
objt ro BitFields:Obj
|
|
||||||
ro that:Int & 1
|
|
||||||
ro this:Int & 24 298
|
|
||||||
|
|
||||||
objt ro Init:Obj
|
|
||||||
ro that:String "hello world"
|
|
||||||
ro this:Int 23
|
|
||||||
|
|
||||||
objt ro ComplexInit:Obj
|
|
||||||
ro whatever:Int:3
|
|
||||||
230984
|
|
||||||
849 394580
|
|
||||||
ro complex0:Bird
|
|
||||||
.that 98
|
|
||||||
.this 2
|
|
||||||
ro complex1:Bird
|
|
||||||
.that 98902
|
|
||||||
.this 235
|
|
||||||
ro basic:Int 87
|
|
@ -7,12 +7,12 @@ data ro aExternalData:Int
|
|||||||
data ro bSingleValue:Int 342
|
data ro bSingleValue:Int 342
|
||||||
|
|
||||||
data ro cNestedObject:Obj
|
data ro cNestedObject:Obj
|
||||||
.this
|
-- this
|
||||||
.bird0 324
|
-- bird0 324
|
||||||
.bird1 "hello world"
|
-- bird1 "hello world"
|
||||||
.that
|
-- that
|
||||||
.bird2 123.8439
|
-- bird2 123.8439
|
||||||
.bird3 9328.21348239
|
-- bird3 9328.21348239
|
||||||
|
|
||||||
data ro dUninitialized:Int:16:mut
|
data ro dUninitialized:Int:16:mut
|
||||||
|
|
||||||
@ -28,9 +28,9 @@ func ro fComplexFunction
|
|||||||
398 9 2309 983 -2387
|
398 9 2309 983 -2387
|
||||||
478 555 123
|
478 555 123
|
||||||
= bird:Bird
|
= bird:Bird
|
||||||
.that
|
-- that
|
||||||
.whenYou 99999
|
-- whenYou 99999
|
||||||
.this 324
|
-- this 324
|
||||||
|
|
||||||
func ro gExternalFunction
|
func ro gExternalFunction
|
||||||
> x:Int
|
> x:Int
|
||||||
|
@ -1,10 +1,35 @@
|
|||||||
:arf
|
:arf
|
||||||
---
|
---
|
||||||
type ro Basic:Int
|
type ro aBasic:Obj:(
|
||||||
|
.ro that:Int
|
||||||
|
.ro this:Int)
|
||||||
|
|
||||||
type ro BasicInit:Int 6
|
type ro bBitFields:Obj:(
|
||||||
|
.ro that:Int & 1
|
||||||
|
.ro this:Int:<298> & 24)
|
||||||
|
|
||||||
type ro IntArray:{Int ..}
|
type ro cInit:Obj:(
|
||||||
|
.ro that:String:<"hello world">
|
||||||
|
.ro this:Int:<23>)
|
||||||
|
|
||||||
type ro IntArrayInit:Int:3
|
type ro dInitInherit:aBasic:(
|
||||||
3298 923 92
|
.that:<9384>
|
||||||
|
.this:<389>)
|
||||||
|
|
||||||
|
type ro eInitAndDefine:aBasic:(
|
||||||
|
.this:<389>
|
||||||
|
.ro these:aBasic:(
|
||||||
|
.ro born:Int:<4>
|
||||||
|
.ro in:Int
|
||||||
|
.ro the:Int:3:<9348 92384 92834>
|
||||||
|
.this:<98>)
|
||||||
|
.that:<9384>)
|
||||||
|
|
||||||
|
type ro fBasic:Int
|
||||||
|
|
||||||
|
type ro gBasicInit:Int:<6>
|
||||||
|
|
||||||
|
type ro hIntArray:{Int ..}
|
||||||
|
|
||||||
|
type ro iIntArrayInit:Int:3:
|
||||||
|
<3298 923 92>
|
||||||
|
Reference in New Issue
Block a user