Merge pull request 'type-section-rework' (#6) from type-section-rework into main
Reviewed-on: arf/arf#6
This commit is contained in:
		
						commit
						844b1562c4
					
				@ -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)
 | 
				
			||||||
		err = parser.nextToken()
 | 
						if err != nil { return }
 | 
				
			||||||
		if err != nil { return }
 | 
						err = parser.nextToken()
 | 
				
			||||||
 | 
						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,34 +61,62 @@ 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 { }
 | 
							if err != nil { return }
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		// get name
 | 
							var member EnumMember
 | 
				
			||||||
		err = parser.nextToken(lexer.TokenKindName)
 | 
							member, err = parser.parseEnumMember()
 | 
				
			||||||
 | 
							into.members = append(into.members, member)
 | 
				
			||||||
 | 
							if err != nil { return }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = parser.expect(lexer.TokenKindNewline)
 | 
				
			||||||
		if err != nil { return }
 | 
							if err != nil { return }
 | 
				
			||||||
		member.location = parser.token.Location()
 | 
					 | 
				
			||||||
		member.name = parser.token.Value().(string)
 | 
					 | 
				
			||||||
		err = parser.nextToken()
 | 
							err = parser.nextToken()
 | 
				
			||||||
		if err != nil { return }
 | 
							if err != nil { return }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// parse default value
 | 
					// parseEnumMember parses a single enum member. Indenttion level is assumed.
 | 
				
			||||||
		if parser.token.Is(lexer.TokenKindNewline) {
 | 
					func (parser *ParsingOperation) parseEnumMember () (
 | 
				
			||||||
			err = parser.nextToken()
 | 
						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 }
 | 
								if err != nil { return }
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			member.value, err = parser.parseInitializationValues(1)
 | 
							} else if parser.token.Is(lexer.TokenKindLParen) {
 | 
				
			||||||
			into.members = append(into.members, member)
 | 
								// parse default values
 | 
				
			||||||
			if err != nil { return }
 | 
								member.value, err = parser.parseObjectDefaultValue()
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			member.value, err = parser.parseArgument()
 | 
					 | 
				
			||||||
			into.members = append(into.members, member)
 | 
					 | 
				
			||||||
			if err != nil { return }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			err = parser.expect(lexer.TokenKindNewline)
 | 
					 | 
				
			||||||
			if err != nil { return }
 | 
					 | 
				
			||||||
			err = parser.nextToken()
 | 
					 | 
				
			||||||
			if err != nil { return }
 | 
								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
 | 
								into.outputs = append(into.outputs, output)
 | 
				
			||||||
			if parser.skimming {
 | 
					 | 
				
			||||||
				err = parser.skipIndentLevel(2)
 | 
					 | 
				
			||||||
				into.outputs = append(into.outputs, output)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// parse default value
 | 
								parser.expect(lexer.TokenKindNewline)
 | 
				
			||||||
			if parser.token.Is(lexer.TokenKindNewline) {
 | 
								if err != nil { return }
 | 
				
			||||||
				err = parser.nextToken()
 | 
								err = parser.nextToken()
 | 
				
			||||||
				if err != nil { return }
 | 
								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 }
 | 
					 | 
				
			||||||
				err = parser.nextToken()
 | 
					 | 
				
			||||||
				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 {
 | 
				
			||||||
 | 
							phrase.block, err = parser.parseBlock(indent + 1)
 | 
				
			||||||
	// if it is any of those, parse the block under it
 | 
						}
 | 
				
			||||||
	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")
 | 
				
			||||||
func (declaration Declaration) ToString () (output string) {
 | 
								for _, member := range what.members {
 | 
				
			||||||
	output += declaration.name + ":"
 | 
									output += member.ToString(indent, breakLine)
 | 
				
			||||||
	output += declaration.what.ToString()
 | 
								}
 | 
				
			||||||
	return
 | 
								output += doIndent(indent, ")")
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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,18 +411,9 @@ 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 :=
 | 
							output += " " + argument.ToString(0, false)
 | 
				
			||||||
			argument.kind == ArgumentKindObjectInitializationValues ||
 | 
					 | 
				
			||||||
			argument.kind == ArgumentKindArrayInitializationValues
 | 
					 | 
				
			||||||
		if isInitializationValue {
 | 
					 | 
				
			||||||
			initializationValues = argument
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			output += " " + argument.ToString(0, false)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	output += "]"
 | 
						output += "]"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -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) {
 | 
						if err != nil { return }
 | 
				
			||||||
		err = parser.nextToken()
 | 
						err = parser.nextToken()
 | 
				
			||||||
		if err != nil { return }
 | 
						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 }
 | 
					 | 
				
			||||||
		err = parser.nextToken()
 | 
					 | 
				
			||||||
		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