mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
Start supporting numbers and strings
This commit is contained in:
7
src/comment.go
Normal file
7
src/comment.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
var commentCompile = makeRegex("( *)//.*")
|
||||
|
||||
func isComment(code UNPARSEcode) bool {
|
||||
return commentCompile.MatchString(code.code)
|
||||
}
|
||||
102
src/import.go
Normal file
102
src/import.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func FileExists(filename string) bool {
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
return true
|
||||
|
||||
} else if errors.Is(err, os.ErrNotExist) {
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func readFile(path string) []UNPARSEcode {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
// optionally, resize scanner's capacity for lines over 64K, see next example
|
||||
output := []UNPARSEcode{}
|
||||
line := 1
|
||||
for scanner.Scan() {
|
||||
output = append(output, UNPARSEcode{scanner.Text(), line})
|
||||
line++
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func importMod(realpath string, origin string, main bool) string {
|
||||
extention := filepath.Ext(realpath)
|
||||
path := realpath
|
||||
if extention == "" {
|
||||
path += ".ar"
|
||||
}
|
||||
ex, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
executable, err := os.Executable()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
executable = filepath.Dir(executable)
|
||||
isABS := filepath.IsAbs(path)
|
||||
var pathsToTest []string
|
||||
if isABS {
|
||||
pathsToTest = []string{
|
||||
filepath.Join(path),
|
||||
filepath.Join(realpath, "init.ar"),
|
||||
}
|
||||
} else {
|
||||
pathsToTest = []string{
|
||||
filepath.Join(origin, realpath, "init.ar"),
|
||||
filepath.Join(origin, path),
|
||||
filepath.Join(origin, "modules", path),
|
||||
filepath.Join(origin, "modules", realpath, "init.ar"),
|
||||
filepath.Join(ex, path),
|
||||
filepath.Join(ex, "modules", realpath, "init.ar"),
|
||||
filepath.Join(ex, "modules", path),
|
||||
filepath.Join(executable, "modules", realpath, "init.ar"),
|
||||
filepath.Join(executable, "modules", path),
|
||||
}
|
||||
}
|
||||
|
||||
var p string
|
||||
var found bool
|
||||
for _, p = range pathsToTest {
|
||||
if FileExists(p) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return "File does not exist: " + realpath
|
||||
}
|
||||
codelines := readFile(p)
|
||||
|
||||
translated, translationerr := translate(codelines)
|
||||
if translationerr != "" {
|
||||
return translationerr
|
||||
}
|
||||
run(translated)
|
||||
return ""
|
||||
}
|
||||
21
src/main.go
21
src/main.go
@@ -1,8 +1,23 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// args without the program path
|
||||
var Args = os.Args[1:]
|
||||
|
||||
func main() {
|
||||
translate("")
|
||||
fmt.Println("hello world")
|
||||
|
||||
ex, e := os.Getwd()
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
if len(Args) == 0 {
|
||||
panic("No file specified")
|
||||
}
|
||||
err := importMod(Args[0], ex, true)
|
||||
if err != "" {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var numberCompile = makeRegex("( *)((\\-)?(([0-9]*(\\.[0-9]+)?)(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)|(0b[10]+(.[10]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?)|(0x[a-fA-F0-9]+(.[a-fA-F0-9]+)?)|(0o[0-7]+(.[0-7]+)?(e((\\-|\\+)?([0-9]+(\\.[0-9]+)?)))?))( *)")
|
||||
|
||||
// a number type
|
||||
type number = *big.Rat
|
||||
|
||||
@@ -19,6 +21,10 @@ func stringToNumber(str string) (*big.Rat, bool) {
|
||||
return newNumber().SetString(str)
|
||||
}
|
||||
|
||||
func isNumber(code UNPARSEcode) bool {
|
||||
return numberCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
// converts a number type to a string
|
||||
func numberToString(num number, fraction int) string {
|
||||
if fraction != 0 {
|
||||
@@ -72,3 +78,12 @@ var subscript = map[byte]string{
|
||||
'8': "₈",
|
||||
'9': "₉",
|
||||
}
|
||||
|
||||
// returns translateNumber, success, error
|
||||
func parseNumber(code UNPARSEcode) (translateNumber, bool, string) {
|
||||
output, _ := newNumber().SetString(code.code)
|
||||
return translateNumber{
|
||||
number: output,
|
||||
line: code.line,
|
||||
}, true, ""
|
||||
}
|
||||
|
||||
14
src/regex.go
Normal file
14
src/regex.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func makeRegex(str string) *regexp.Regexp {
|
||||
Compile, err := regexp.Compile("^(" + str + ")$")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return Compile
|
||||
}
|
||||
24
src/run.go
Normal file
24
src/run.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func runLine(line any) (any, string) {
|
||||
switch line.(type) {
|
||||
case translateNumber:
|
||||
return (numberToString(line.(translateNumber).number, 0)), ""
|
||||
case translateString:
|
||||
return (line.(translateString).str), ""
|
||||
}
|
||||
return nil, "Error: invalid code on line " + fmt.Sprint(line.(translateNumber).line) + ": " + line.(translateNumber).code
|
||||
}
|
||||
|
||||
// returns error
|
||||
func run(translated []any) (any, string) {
|
||||
for _, val := range translated {
|
||||
_, err := runLine(val)
|
||||
if err != "" {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, ""
|
||||
}
|
||||
42
src/string.go
Normal file
42
src/string.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var stringCompile = makeRegex("(( *)\"((\\\\([a-z\\\"'`]))|[^\\\"])*\"( *))|(( *)'((\\\\([a-z\\'\"`]))|[^\\'])*'( *))")
|
||||
|
||||
func isString(code UNPARSEcode) bool {
|
||||
return stringCompile.MatchString(code.code)
|
||||
}
|
||||
|
||||
func unquoted(
|
||||
str string,
|
||||
) (string, error) {
|
||||
str = strings.Trim(str, " ")
|
||||
if str[0] == '\'' {
|
||||
str = strings.Replace(str, "\\\"", "\"", -1)
|
||||
str = strings.Replace(str, "\"", "\\\"", -1)
|
||||
}
|
||||
str = str[1 : len(str)-1]
|
||||
str = strings.Replace(str, "\\'", "'", -1)
|
||||
str = "\"" + str + "\""
|
||||
return strconv.Unquote(str)
|
||||
}
|
||||
|
||||
// returns translateString, success, error
|
||||
func parseString(code UNPARSEcode) (translateString, bool, string) {
|
||||
trim := strings.Trim(code.code, " ")
|
||||
|
||||
unquoted, err := unquoted(trim)
|
||||
if err != nil {
|
||||
return translateString{}, false, "Syntax Error: invalid string on line " + fmt.Sprint(code.line) + ": " + code.code
|
||||
}
|
||||
|
||||
return translateString{
|
||||
str: unquoted,
|
||||
line: code.line,
|
||||
}, true, ""
|
||||
}
|
||||
@@ -2,9 +2,42 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
func translate(code string) {
|
||||
output, _ := newNumber().SetString("3.1415")
|
||||
fmt.Println(numberToString(output, 0))
|
||||
// returns (translateNumber | translateString), success, error
|
||||
func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine bool) (any, bool, string) {
|
||||
if isLine {
|
||||
if isComment(code) {
|
||||
return nil, true, ""
|
||||
}
|
||||
}
|
||||
|
||||
if isNumber(code) {
|
||||
return parseNumber(code)
|
||||
} else if isString(code) {
|
||||
return parseString(code)
|
||||
}
|
||||
if isLine {
|
||||
return nil, false, "Syntax Error: invalid code on line " + fmt.Sprint(code.line) + ": " + code.code
|
||||
}
|
||||
return nil, false, ""
|
||||
}
|
||||
|
||||
// returns [](translateNumber | translateString), error
|
||||
func translate(codelines []UNPARSEcode) ([]any, string) {
|
||||
translated := []any{}
|
||||
for i, code := range codelines {
|
||||
val, _, err := translateVal(code, i, codelines, true)
|
||||
|
||||
if err != "" {
|
||||
log.Fatal(err)
|
||||
return nil, err
|
||||
}
|
||||
if val == nil {
|
||||
continue
|
||||
}
|
||||
translated = append(translated, val)
|
||||
}
|
||||
return translated, ""
|
||||
}
|
||||
|
||||
18
src/types.go
Normal file
18
src/types.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
type UNPARSEcode struct {
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
type translateNumber struct {
|
||||
number
|
||||
code string
|
||||
line int
|
||||
}
|
||||
|
||||
type translateString struct {
|
||||
str string
|
||||
code string
|
||||
line int
|
||||
}
|
||||
Reference in New Issue
Block a user