Compare commits

..

7 Commits

Author SHA1 Message Date
40f3ea743a Change new repo link in README 2024-02-27 19:12:45 +00:00
4fb73a3465 Update README.md 2024-02-13 19:14:33 +00:00
58bae14528 wip 2022-10-25 11:26:17 -04:00
4385319874 MMM im so full from phrase analysis 2022-10-25 01:33:07 -04:00
e85e61d70c Add command accessor 2022-10-25 00:20:02 -04:00
e067483942 Updated phrase terminology 2022-10-25 00:02:24 -04:00
4929081d87 wip 2022-10-24 17:15:48 -04:00
7 changed files with 104 additions and 8 deletions

View File

@@ -1,5 +1,9 @@
# ![ARF](assets/logo.svg) # ![ARF](assets/logo.svg)
This repository is no longer being developed. The ARF language has since gone through several revisions and has been given a different name (FSPL), and the new version can be found [here](git.tebibyte.media/fspl/fspl).
README of this repository:
The ARF programming language. The ARF programming language.
This is still under development and does not compile things yet. Once complete, This is still under development and does not compile things yet. Once complete,

View File

@@ -4,7 +4,6 @@ import "git.tebibyte.media/arf/arf/parser"
// Block represents a scoped block of phrases. // Block represents a scoped block of phrases.
type Block struct { type Block struct {
locatable
phrases []Phrase phrases []Phrase
// TODO: create a scope struct and embed it // TODO: create a scope struct and embed it
@@ -14,7 +13,10 @@ func (block Block) ToString (indent int) (output string) {
output += doIndent(indent, "block\n") output += doIndent(indent, "block\n")
// TODO: variables // TODO: variables
// TODO: phrases
for _, phrase := range block.phrases {
output += phrase.ToString(indent + 1)
}
return return
} }
@@ -27,5 +29,11 @@ func (analyzer *analysisOperation) analyzeBlock (
block Block, block Block,
err error, err error,
) { ) {
for _, inputPhrase := range inputBlock {
var outputPhrase Phrase
outputPhrase, err = analyzer.analyzePhrase(inputPhrase)
block.phrases = append(block.phrases, outputPhrase)
}
return return
} }

View File

@@ -52,6 +52,9 @@ func (analyzer *analysisOperation) analyzeFuncSection () (
if inputSection.External() { if inputSection.External() {
outputSection.external = true outputSection.external = true
if inputSection.Root() != nil {
panic("invalid state: input func is external with non-nil root")
}
} else { } else {
outputSection.root, err = analyzer.analyzeBlock(inputSection.Root()) outputSection.root, err = analyzer.analyzeBlock(inputSection.Root())

View File

@@ -1,9 +1,12 @@
package analyzer package analyzer
import "regexp"
import "git.tebibyte.media/arf/arf/file" import "git.tebibyte.media/arf/arf/file"
import "git.tebibyte.media/arf/arf/parser" import "git.tebibyte.media/arf/arf/parser"
import "git.tebibyte.media/arf/arf/infoerr" import "git.tebibyte.media/arf/arf/infoerr"
var validNameRegex = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
type Phrase interface { type Phrase interface {
// Provided by phraseBase // Provided by phraseBase
Location () (location file.Location) Location () (location file.Location)
@@ -19,6 +22,17 @@ type ArbitraryPhrase struct {
arguments []Argument arguments []Argument
} }
func (phrase ArbitraryPhrase) ToString (indent int) (output string) {
output += doIndent(indent, "phrase\n")
output += doIndent(indent + 1, phrase.command, "\n")
for _, argument := range phrase.arguments {
output += argument.ToString(indent + 1)
}
return
}
type CastPhrase struct { type CastPhrase struct {
phraseBase phraseBase
command Argument command Argument
@@ -33,5 +47,41 @@ func (analyzer *analysisOperation) analyzePhrase (
phrase Phrase, phrase Phrase,
err error, err error,
) { ) {
base := phraseBase { }
base.location = inputPhrase.Location()
arguments := []Argument { }
for index := 0; index < inputPhrase.Length(); index ++ {
inputArgument := inputPhrase.Argument(index)
var argument Argument
argument, err = analyzer.analyzeArgument(inputArgument)
if err != nil { return }
arguments = append(arguments, argument)
}
switch inputPhrase.Kind() {
case parser.PhraseKindArbitrary:
command := inputPhrase.Command().Value().(string)
if !validNameRegex.Match([]byte(command)) {
err = inputPhrase.NewError (
"command cannot contain characters other " +
"than a-z, A-Z, 0-9, underscores, or begin " +
"with a number",
infoerr.ErrorKindError)
return
}
outputPhrase := ArbitraryPhrase {
phraseBase: base,
command: command,
arguments: arguments,
}
phrase = outputPhrase
default:
panic("phrase kind not implemented")
}
return return
} }

View File

@@ -191,6 +191,12 @@ func (section DataSection) External () (external bool) {
return return
} }
// Command returns the phrase's command.
func (phrase Phrase) Command () (command Argument) {
command = phrase.command
return
}
// Kind returns what kind of phrase it is. // Kind returns what kind of phrase it is.
func (phrase Phrase) Kind () (kind PhraseKind) { func (phrase Phrase) Kind () (kind PhraseKind) {
kind = phrase.kind kind = phrase.kind

View File

@@ -306,7 +306,7 @@ func (parser *parsingOperation) parsePhraseCommand () (
// determine semantic role of phrase // determine semantic role of phrase
if command.kind == ArgumentKindString { if command.kind == ArgumentKindString {
kind = PhraseKindCallExternal kind = PhraseKindArbitrary
} else if command.kind == ArgumentKindIdentifier { } else if command.kind == ArgumentKindIdentifier {
identifier := command.value.(Identifier) identifier := command.value.(Identifier)

View File

@@ -231,33 +231,58 @@ type Dereference struct {
type PhraseKind int type PhraseKind int
const ( const (
PhraseKindCall = iota // [name]
PhraseKindCallExternal PhraseKindCall PhraseKind = iota
// ["name"]
PhraseKindArbitrary
// [+] [-]
PhraseKindOperator PhraseKindOperator
// [= x y]
PhraseKindAssign PhraseKindAssign
// [loc x]
PhraseKindReference PhraseKindReference
// [cast x T]
PhraseKindCast PhraseKindCast
// [defer]
PhraseKindDefer PhraseKindDefer
// [if c]
PhraseKindIf PhraseKindIf
// [elseif]
PhraseKindElseIf PhraseKindElseIf
// [else]
PhraseKindElse PhraseKindElse
// [switch]
PhraseKindSwitch PhraseKindSwitch
// [case]
PhraseKindCase PhraseKindCase
// [while c]
PhraseKindWhile PhraseKindWhile
// [for x y z]
PhraseKindFor PhraseKindFor
) )
// Phrase represents a function call or operator. In ARF they are the same // Phrase represents a function call or operator. In ARF they are the same
// syntactical concept. // syntactical concept.
type Phrase struct { type Phrase struct {
location file.Location locatable
returnees []Argument returnees []Argument
multiValuable multiValuable
kind PhraseKind kind PhraseKind
// TODO: do not have this be an argument. make a string version, and
// and identifier version.
command Argument command Argument
// only applicable for PhraseKindOperator // only applicable for PhraseKindOperator