Compare commits

..

9 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
befe371e4f What is anything anymore 2022-10-24 01:16:07 -04:00
dfa7d31163 Methods do not collide and are properly retrievable 2022-10-23 02:24:34 -04:00
10 changed files with 162 additions and 18 deletions

View File

@@ -1,5 +1,9 @@
# ![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.
This is still under development and does not compile things yet. Once complete,

View File

@@ -58,7 +58,7 @@ func (analyzer *analysisOperation) analyze () (err error) {
for !sections.End() {
_, err = analyzer.fetchSection(locator {
modulePath: analyzer.modulePath,
name: sections.Value().Name(),
name: sections.Key(),
})
if err != nil { return err }
sections.Next()
@@ -93,7 +93,7 @@ func (analyzer *analysisOperation) fetchSection (
return
}
var parsedSection = tree.LookupSection(where.name)
var parsedSection = tree.LookupSection("", where.name)
if parsedSection == nil {
section = nil
return

View File

@@ -1,5 +1,39 @@
package analyzer
import "git.tebibyte.media/arf/arf/parser"
// Block represents a scoped block of phrases.
type Block struct {
locatable
phrases []Phrase
// TODO: create a scope struct and embed it
}
func (block Block) ToString (indent int) (output string) {
output += doIndent(indent, "block\n")
// TODO: variables
for _, phrase := range block.phrases {
output += phrase.ToString(indent + 1)
}
return
}
// analyzeBlock analyzes a scoped block of phrases.
// TODO: have a way to "start out" with a list of variables for things like
// arguments, and declarations inside of control flow statements
func (analyzer *analysisOperation) analyzeBlock (
inputBlock parser.Block,
) (
block Block,
err error,
) {
for _, inputPhrase := range inputBlock {
var outputPhrase Phrase
outputPhrase, err = analyzer.analyzePhrase(inputPhrase)
block.phrases = append(block.phrases, outputPhrase)
}
return
}

View File

@@ -7,7 +7,8 @@ import "git.tebibyte.media/arf/arf/infoerr"
// FuncSection represents a type definition section.
type FuncSection struct {
sectionBase
external bool
root Block
external bool
}
// ToString returns all data stored within the function section, in string form.
@@ -18,7 +19,7 @@ func (section FuncSection) ToString (indent int) (output string) {
output += "\n"
// TODO: arguments
// TODO: root block
output += section.root.ToString(indent + 1)
return
}
@@ -51,8 +52,13 @@ func (analyzer *analysisOperation) analyzeFuncSection () (
if inputSection.External() {
outputSection.external = true
if inputSection.Root() != nil {
panic("invalid state: input func is external with non-nil root")
}
} else {
outputSection.root, err = analyzer.analyzeBlock(inputSection.Root())
if err != nil { return }
// TODO: analyze root block if not nil
}

View File

@@ -1,9 +1,12 @@
package analyzer
import "regexp"
import "git.tebibyte.media/arf/arf/file"
import "git.tebibyte.media/arf/arf/parser"
import "git.tebibyte.media/arf/arf/infoerr"
var validNameRegex = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
type Phrase interface {
// Provided by phraseBase
Location () (location file.Location)
@@ -19,6 +22,17 @@ type ArbitraryPhrase struct {
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 {
phraseBase
command Argument
@@ -33,5 +47,41 @@ func (analyzer *analysisOperation) analyzePhrase (
phrase Phrase,
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
}

View File

@@ -3,8 +3,17 @@ package parser
import "git.tebibyte.media/arf/arf/types"
// LookupSection looks returns the section under the give name. If the section
// does not exist, nil is returned.
func (tree SyntaxTree) LookupSection (name string) (section Section) {
// does not exist, nil is returned. If a method is being searched for, the type
// name of its receiver should be passed. If not, it should just be left blank.
func (tree SyntaxTree) LookupSection (
receiver string,
name string,
) (
section Section,
) {
if receiver != "" {
name = receiver + "_" + name
}
section = tree.sections[name]
return
}
@@ -182,6 +191,12 @@ func (section DataSection) External () (external bool) {
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.
func (phrase Phrase) Kind () (kind PhraseKind) {
kind = phrase.kind

View File

@@ -53,7 +53,17 @@ func (parser *parsingOperation) parseBody () (err error) {
// addSection adds a section to the tree, ensuring it has a unique name within
// the module.
func (tree *SyntaxTree) addSection (section Section) (err error) {
_, exists := tree.sections[section.Name()]
index := section.Name()
funcSection, isFuncSection := section.(FuncSection)
if isFuncSection {
receiver := funcSection.receiver
if receiver != nil {
index = receiver.what.points.name.trail[0] + "_" + index
}
}
_, exists := tree.sections[index]
if exists {
err = section.NewError (
"cannot have multiple sections with the same name",
@@ -61,6 +71,6 @@ func (tree *SyntaxTree) addSection (section Section) (err error) {
return
}
tree.sections[section.Name()] = section
tree.sections[index] = section
return
}

View File

@@ -6,13 +6,13 @@ func TestFunc (test *testing.T) {
checkTree ("../tests/parser/func", false,
`:arf
---
func ro aBasicExternal
func ro bMethod
@ bird:{Bird}
> someInput:Int:mut
< someOutput:Int 4
---
external
func ro bMethod
@ bird:{Bird}
func ro aBasicExternal
> someInput:Int:mut
< someOutput:Int 4
---

View File

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

View File

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