diff --git a/parser/func.go b/parser/func.go index 366e732..1ee5302 100644 --- a/parser/func.go +++ b/parser/func.go @@ -4,15 +4,6 @@ import "git.tebibyte.media/arf/arf/types" import "git.tebibyte.media/arf/arf/lexer" import "git.tebibyte.media/arf/arf/infoerr" -// controlFlowNames contains a list of all command names that must have a block -// underneath them. -var controlFlowNames = []string { - "if", "else", "elseif", - "for", "while", - "switch", - "defer", -} - // parseFunc parses a function section. func (parser *ParsingOperation) parseFuncSection () ( section *FuncSection, diff --git a/parser/phrase.go b/parser/phrase.go index da0f8d5..66fb40d 100644 --- a/parser/phrase.go +++ b/parser/phrase.go @@ -72,6 +72,14 @@ var validDelimitedPhraseTokens = append ( lexer.TokenKindRBracket, lexer.TokenKindReturnDirection) +// controlFlowNames contains a list of all command names that must have a block +// underneath them. +var controlFlowNames = []string { + "if", "else", "elseif", + "for", "while", + "defer", +} + // parseBlock parses an indented block of phrases func (parser *ParsingOperation) parseBlock ( indent int, @@ -205,6 +213,23 @@ 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 isControlFlow { + phrase.block, err = parser.parseBlock(indent + 1) + } + return } diff --git a/parser/tree-tostring.go b/parser/tree-tostring.go index 5353ec6..393320e 100644 --- a/parser/tree-tostring.go +++ b/parser/tree-tostring.go @@ -154,30 +154,6 @@ func (values ArrayInitializationValues) ToString ( return } -func (phrase Phrase) ToString (indent int, ownLine bool) (output string) { - if ownLine { - output += doIndent(indent) - } - - output += "[" + phrase.command.ToString(0, false) - for _, argument := range phrase.arguments { - output += " " + argument.ToString(0, false) - } - output += "]" - - if len(phrase.returnsTo) > 0 { - output += " ->" - for _, returnItem := range phrase.returnsTo { - output += " " + returnItem.ToString(0, false) - } - } - - if ownLine { - output += "\n" - } - return -} - func (argument *Argument) ToString (indent int, breakLine bool) (output string) { if !breakLine { indent = 0 } if argument.kind == ArgumentKindNil { @@ -446,6 +422,31 @@ func (behavior *FaceBehavior) ToString (indent int) (output string) { return } +func (phrase Phrase) ToString (indent int, ownLine bool) (output string) { + if ownLine { + output += doIndent(indent) + } + + output += "[" + phrase.command.ToString(0, false) + for _, argument := range phrase.arguments { + output += " " + argument.ToString(0, false) + } + output += "]" + + if len(phrase.returnsTo) > 0 { + output += " ->" + for _, returnItem := range phrase.returnsTo { + output += " " + returnItem.ToString(0, false) + } + } + + if ownLine { + output += "\n" + output += phrase.block.ToString(indent + 1) + } + return +} + func (block Block) ToString (indent int) (output string) { for _, phrase := range block { output += phrase.ToString(indent, true) diff --git a/parser/tree.go b/parser/tree.go index 3a2117d..4c25f8d 100644 --- a/parser/tree.go +++ b/parser/tree.go @@ -79,15 +79,6 @@ type ArrayInitializationValues struct { values []Argument } -// Phrase represents a function call or operator. In ARF they are the same -// syntactical concept. -type Phrase struct { - location file.Location - command Argument - arguments []Argument - returnsTo []Argument -} - // ArgumentKind specifies the type of thing the value of an argument should be // cast to. type ArgumentKind int @@ -232,9 +223,19 @@ type FaceSection struct { behaviors map[string] FaceBehavior } +// Phrase represents a function call or operator. In ARF they are the same +// syntactical concept. +type Phrase struct { + location file.Location + command Argument + arguments []Argument + returnsTo []Argument + + // only applicable for + block Block +} + // Block represents a scoped/indented block of code. -// TODO: blocks will not directly nest. nested blocks will be stored as a part -// of certain control flow statements. type Block []Phrase // FuncOutput represents an input a function section. It is unlike an input in