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) # ![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

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

View File

@@ -1,5 +1,39 @@
package analyzer package analyzer
import "git.tebibyte.media/arf/arf/parser"
// Block represents a scoped block of phrases.
type Block struct { 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. // FuncSection represents a type definition section.
type FuncSection struct { type FuncSection struct {
sectionBase sectionBase
external bool root Block
external bool
} }
// ToString returns all data stored within the function section, in string form. // 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" output += "\n"
// TODO: arguments // TODO: arguments
// TODO: root block output += section.root.ToString(indent + 1)
return return
} }
@@ -51,8 +52,13 @@ 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())
if err != nil { return }
// TODO: analyze root block if not nil // TODO: analyze root block if not nil
} }

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

@@ -3,8 +3,17 @@ package parser
import "git.tebibyte.media/arf/arf/types" import "git.tebibyte.media/arf/arf/types"
// LookupSection looks returns the section under the give name. If the section // LookupSection looks returns the section under the give name. If the section
// does not exist, nil is returned. // does not exist, nil is returned. If a method is being searched for, the type
func (tree SyntaxTree) LookupSection (name string) (section Section) { // 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] section = tree.sections[name]
return return
} }
@@ -182,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

@@ -53,7 +53,17 @@ func (parser *parsingOperation) parseBody () (err error) {
// addSection adds a section to the tree, ensuring it has a unique name within // addSection adds a section to the tree, ensuring it has a unique name within
// the module. // the module.
func (tree *SyntaxTree) addSection (section Section) (err error) { 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 { if exists {
err = section.NewError ( err = section.NewError (
"cannot have multiple sections with the same name", "cannot have multiple sections with the same name",
@@ -61,6 +71,6 @@ func (tree *SyntaxTree) addSection (section Section) (err error) {
return return
} }
tree.sections[section.Name()] = section tree.sections[index] = section
return return
} }

View File

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

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