Blocks under control flow phrases now parse
... except for switch cases. This will be added momentarily.
This commit is contained in:
parent
837b1c76a4
commit
bcd44828dc
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user