diff --git a/lexer/token.go b/lexer/token.go index 466785f..66c7a4c 100644 --- a/lexer/token.go +++ b/lexer/token.go @@ -75,6 +75,14 @@ type Token struct { value any } +// NewToken provides a way for a new token to be created by other modules for +// comparison purposes. +func NewToken (kind TokenKind, value any) (token Token) { + token.kind = kind + token.value = value + return +} + // Kind returns the semantic role of the token. func (token Token) Kind () (kind TokenKind) { return token.kind diff --git a/parser/phrase.go b/parser/phrase.go index 66fb40d..9e8c38d 100644 --- a/parser/phrase.go +++ b/parser/phrase.go @@ -5,6 +5,7 @@ import "git.tebibyte.media/arf/arf/lexer" // operatorTokens lists all symbolic tokens that can act as a command to a // phrase. var operatorTokens = []lexer.TokenKind { + lexer.TokenKindColon, lexer.TokenKindPlus, lexer.TokenKindMinus, lexer.TokenKindIncrement, @@ -213,22 +214,33 @@ func (parser *ParsingOperation) parseBlockLevelPhrase ( err = parser.nextToken() if err != nil { return } - // if this is a control flow statement, parse - if phrase.command.kind != ArgumentKindIdentifier { return } - command := phrase.command.value.(Identifier) - if len(command.trail) != 1 { return } - - isControlFlow := false - for _, name := range controlFlowNames { - if command.trail[0] == name { - isControlFlow = true - break + // if this is a control flow statement, parse block under it + if phrase.command.kind == ArgumentKindIdentifier { + // perhaps it is a normal control flow statement? + command := phrase.command.value.(Identifier) + if len(command.trail) != 1 { return } + + isControlFlow := false + for _, name := range controlFlowNames { + if command.trail[0] == name { + isControlFlow = true + break + } } + + if !isControlFlow { return } + + } else if phrase.command.kind == ArgumentKindOperator { + // perhaps it is a switch case? + command := phrase.command.value.(lexer.TokenKind) + if command != lexer.TokenKindColon { return } + + } else { + 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 } diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 393320e..a4443d9 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -209,6 +209,8 @@ func (argument *Argument) ToString (indent int, breakLine bool) (output string) case ArgumentKindOperator: var stringValue string switch argument.value.(lexer.TokenKind) { + case lexer.TokenKindColon: + stringValue = ":" case lexer.TokenKindPlus: stringValue = "+" case lexer.TokenKindMinus: diff --git a/tests/parser/func/main.arf b/tests/parser/func/main.arf index dd44b76..262644c 100644 --- a/tests/parser/func/main.arf +++ b/tests/parser/func/main.arf @@ -121,7 +121,7 @@ func ro gControlFlow else otherThing -func hSetPhrase +func ro hSetPhrase --- set x:Int 3 # TODO: this should be the "location of" phrase. update other things to