This commit is contained in:
2023-06-19 23:59:42 +01:00
13 changed files with 415 additions and 51 deletions

View File

@@ -13,7 +13,18 @@ func anyToBool(x any) bool {
case nil: case nil:
return false return false
case ArObject: case ArObject:
return anyToBool(ArValidToAny(x)) if y, ok := x.obj["__Boolean__"]; ok {
val, err := runCall(
call{
callable: y,
args: []any{},
}, stack{}, 0)
if err.EXISTS {
return false
}
return anyToBool(val)
}
return false
case builtinFunc: case builtinFunc:
return true return true
case Callable: case Callable:

View File

@@ -150,8 +150,35 @@ func makeGlobal() ArObject {
vars["cot"] = ArCot vars["cot"] = ArCot
vars["arccot"] = ArArccot vars["arccot"] = ArArccot
vars["todeg"] = ArToDeg vars["todeg"] = ArToDeg
vars["colour"] = ArColour
vars["torad"] = ArToRad vars["torad"] = ArToRad
vars["abs"] = ArAbs vars["abs"] = ArAbs
vars["fraction"] = builtinFunc{"fraction", func(a ...any) (any, ArErr) {
if len(a) == 0 {
return nil, ArErr{TYPE: "fraction", message: "fraction takes 1 argument",
EXISTS: true}
}
switch x := a[0].(type) {
case number:
return ArString(x.String()), ArErr{}
case ArObject:
if callable, ok := x.obj["__fraction__"]; ok {
resp, err := runCall(
call{
callable: callable,
args: []any{},
},
stack{},
0,
)
if err.EXISTS {
return nil, err
}
return resp, ArErr{}
}
}
return nil, ArErr{TYPE: "TypeError", message: "Cannot fraction '" + typeof(a[0]) + "'", EXISTS: true}
}}
vars["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) { vars["dir"] = builtinFunc{"dir", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {
return ArArray([]any{}), ArErr{} return ArArray([]any{}), ArErr{}
@@ -163,6 +190,26 @@ func makeGlobal() ArObject {
for key := range x.obj { for key := range x.obj {
newarray = append(newarray, key) newarray = append(newarray, key)
} }
if callable, ok := x.obj["__dir__"]; ok {
resp, err := runCall(
call{
callable: callable,
args: []any{},
},
stack{newscope()},
0,
)
if err.EXISTS {
return nil, err
}
resp = ArValidToAny(resp)
switch x := resp.(type) {
case []any:
newarray = append(newarray, x...)
default:
return nil, ArErr{TYPE: "TypeError", message: "__dir__ returned type '" + typeof(x) + "'", EXISTS: true}
}
}
return ArArray(newarray), ArErr{} return ArArray(newarray), ArErr{}
} }
return ArArray([]any{}), ArErr{} return ArArray([]any{}), ArErr{}

96
src/colour.go Normal file
View File

@@ -0,0 +1,96 @@
package main
import (
"fmt"
"github.com/fatih/color"
"github.com/jwalton/go-supportscolor"
)
var ArColour = Map(
anymap{
"set": builtinFunc{"set", func(a ...any) (any, ArErr) {
if len(a) != 2 {
return nil, ArErr{
TYPE: "TypeError",
message: "set() takes exactly 2 argument (" + fmt.Sprint(len(a)) + " given)",
EXISTS: true,
}
}
var c *color.Color
var s string
if x, ok := a[0].(number); ok {
c = color.Set(color.Attribute(x.Num().Int64()))
} else {
return nil, ArErr{
TYPE: "TypeError",
message: "set() argument 1 must be an number, not " + typeof(a[0]),
EXISTS: true,
}
}
if typeof(a[1]) == "string" {
s = ArValidToAny(a[1]).(string)
} else {
return nil, ArErr{
TYPE: "TypeError",
message: "set() argument 2 must be a string, not " + typeof(a[1]),
EXISTS: true,
}
}
if supportscolor.Stdout().SupportsColor {
return c.Sprint(s), ArErr{}
} else {
return s, ArErr{}
}
}},
"bg": Map(
anymap{
"black": newNumber().SetInt64(int64(color.BgBlack)),
"red": newNumber().SetInt64(int64(color.BgRed)),
"green": newNumber().SetInt64(int64(color.BgGreen)),
"yellow": newNumber().SetInt64(int64(color.BgYellow)),
"blue": newNumber().SetInt64(int64(color.BgBlue)),
"magenta": newNumber().SetInt64(int64(color.BgMagenta)),
"cyan": newNumber().SetInt64(int64(color.BgCyan)),
"white": newNumber().SetInt64(int64(color.BgWhite)),
"hiBlack": newNumber().SetInt64(int64(color.BgHiBlack)),
"hiRed": newNumber().SetInt64(int64(color.BgHiRed)),
"hiGreen": newNumber().SetInt64(int64(color.BgHiGreen)),
"hiYellow": newNumber().SetInt64(int64(color.BgHiYellow)),
"hiBlue": newNumber().SetInt64(int64(color.BgHiBlue)),
"hiMagenta": newNumber().SetInt64(int64(color.BgHiMagenta)),
"hiCyan": newNumber().SetInt64(int64(color.BgHiCyan)),
"hiWhite": newNumber().SetInt64(int64(color.BgHiWhite)),
},
),
"fg": Map(
anymap{
"black": newNumber().SetInt64(int64(color.FgBlack)),
"red": newNumber().SetInt64(int64(color.FgRed)),
"green": newNumber().SetInt64(int64(color.FgGreen)),
"yellow": newNumber().SetInt64(int64(color.FgYellow)),
"blue": newNumber().SetInt64(int64(color.FgBlue)),
"magenta": newNumber().SetInt64(int64(color.FgMagenta)),
"cyan": newNumber().SetInt64(int64(color.FgCyan)),
"white": newNumber().SetInt64(int64(color.FgWhite)),
"hiBlack": newNumber().SetInt64(int64(color.FgHiBlack)),
"hiRed": newNumber().SetInt64(int64(color.FgHiRed)),
"hiGreen": newNumber().SetInt64(int64(color.FgHiGreen)),
"hiYellow": newNumber().SetInt64(int64(color.FgHiYellow)),
"hiBlue": newNumber().SetInt64(int64(color.FgHiBlue)),
"hiMagenta": newNumber().SetInt64(int64(color.FgHiMagenta)),
"hiCyan": newNumber().SetInt64(int64(color.FgHiCyan)),
"hiWhite": newNumber().SetInt64(int64(color.FgHiWhite)),
},
),
"reset": newNumber().SetInt64(int64(color.Reset)),
"bold": newNumber().SetInt64(int64(color.Bold)),
"faint": newNumber().SetInt64(int64(color.Faint)),
"italic": newNumber().SetInt64(int64(color.Italic)),
"underline": newNumber().SetInt64(int64(color.Underline)),
"blinkSlow": newNumber().SetInt64(int64(color.BlinkSlow)),
"blinkRapid": newNumber().SetInt64(int64(color.BlinkRapid)),
"reverseVideo": newNumber().SetInt64(int64(color.ReverseVideo)),
"concealed": newNumber().SetInt64(int64(color.Concealed)),
"crossedOut": newNumber().SetInt64(int64(color.CrossedOut)),
})

View File

@@ -11,6 +11,8 @@ import (
var imported = make(map[string]ArObject) var imported = make(map[string]ArObject)
var importing = make(map[string]bool) var importing = make(map[string]bool)
var modules_folder = "argon_modules"
func FileExists(filename string) bool { func FileExists(filename string) bool {
if _, err := os.Stat(filename); err == nil { if _, err := os.Stat(filename); err == nil {
return true return true
@@ -73,13 +75,13 @@ func importMod(realpath string, origin string, main bool, global ArObject) (ArOb
pathsToTest = []string{ pathsToTest = []string{
filepath.Join(origin, realpath, "init.ar"), filepath.Join(origin, realpath, "init.ar"),
filepath.Join(origin, path), filepath.Join(origin, path),
filepath.Join(origin, "modules", path), filepath.Join(origin, modules_folder, path),
filepath.Join(origin, "modules", realpath, "init.ar"), filepath.Join(origin, modules_folder, realpath, "init.ar"),
filepath.Join(ex, path), filepath.Join(ex, path),
filepath.Join(ex, "modules", realpath, "init.ar"), filepath.Join(ex, modules_folder, realpath, "init.ar"),
filepath.Join(ex, "modules", path), filepath.Join(ex, modules_folder, path),
filepath.Join(executable, "modules", realpath, "init.ar"), filepath.Join(executable, modules_folder, realpath, "init.ar"),
filepath.Join(executable, "modules", path), filepath.Join(executable, modules_folder, path),
} }
} }

1
src/infinity.go Normal file
View File

@@ -0,0 +1 @@
package main

View File

@@ -6,7 +6,7 @@ import (
"sync" "sync"
) )
var mapCompiled = makeRegex(`( *)\{(((( *).+( *):( *).+( *))|(` + spacelessVariable + `))(( *)\,(( *).+( *):( *).+( *))|(` + spacelessVariable + `)))*\}( *)`) var mapCompiled = makeRegex(`( )*{( |\n)*(((.|\n)+)(,(.|\n)+)*)?( |\n)*}( )*`)
type createMap struct { type createMap struct {
body anymap body anymap
@@ -19,11 +19,11 @@ func isMap(code UNPARSEcode) bool {
return mapCompiled.MatchString(code.code) return mapCompiled.MatchString(code.code)
} }
func parseMap(code UNPARSEcode) (any, UNPARSEcode) { func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool, ArErr, int) {
trimmed := strings.Trim(code.code, " ") trimmed := strings.TrimSpace(code.code)
trimmed = trimmed[1 : len(trimmed)-1] trimmed = trimmed[1 : len(trimmed)-1]
debugPrintln(trimmed) debugPrintln(trimmed)
return nil, UNPARSEcode{} return Map(anymap{}), true, ArErr{}, 1
} }
func Map(m anymap) ArObject { func Map(m anymap) ArObject {
@@ -211,5 +211,14 @@ func Map(m anymap) ArObject {
return true, ArErr{} return true, ArErr{}
}, },
} }
obj.obj["__dir__"] = builtinFunc{
"__dir__",
func(args ...any) (any, ArErr) {
x := []any{}
for k := range m {
x = append(x, k)
}
return x, ArErr{}
}}
return obj return obj
} }

View File

@@ -66,9 +66,6 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
continue continue
} }
for k := 0; k < len(split)-1; k++ { for k := 0; k < len(split)-1; k++ {
if len(strings.TrimSpace(split[k])) == 0 || len(strings.TrimSpace(split[k+1])) == 0 {
break
}
val1, worked, err, step1 := translateVal(UNPARSEcode{ val1, worked, err, step1 := translateVal(UNPARSEcode{
code: strings.Join(split[:k+1], operations[i][j]), code: strings.Join(split[:k+1], operations[i][j]),
realcode: code.realcode, realcode: code.realcode,
@@ -79,6 +76,9 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
if k == len(split)-1 { if k == len(split)-1 {
return operationType{}, false, err, 0 return operationType{}, false, err, 0
} else { } else {
if len(strings.TrimSpace(split[k])) == 0 || len(strings.TrimSpace(split[k+1])) == 0 {
break
}
continue continue
} }
} }
@@ -93,6 +93,9 @@ func parseOperations(code UNPARSEcode, index int, codelines []UNPARSEcode) (oper
if k == len(split)-1 { if k == len(split)-1 {
return operationType{}, false, err, 0 return operationType{}, false, err, 0
} else { } else {
if len(strings.TrimSpace(split[k])) == 0 || len(strings.TrimSpace(split[k+1])) == 0 {
break
}
continue continue
} }
} }
@@ -143,6 +146,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return anyToBool(val), ArErr{}
}
}
}
if x, ok := resp2.(ArObject); ok {
if y, ok := x.obj["__GreaterThanEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
@@ -170,6 +188,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return anyToBool(val), ArErr{}
}
}
}
if x, ok := resp2.(ArObject); ok {
if y, ok := x.obj["__LessThanEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
@@ -197,12 +230,27 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return anyToBool(val), ArErr{}
}
}
if x, ok := resp2.(ArObject); ok {
if y, ok := x.obj["__GreaterThan__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
return anyToBool(val), ArErr{} return anyToBool(val), ArErr{}
} }
} }
}
return false, ArErr{ return false, ArErr{
"Runtime Error", "Runtime Error",
"Cannot compare type '" + typeof(resp) + "' with type '" + typeof(resp2) + "' with opperation '<'", "Cannot compare type '" + typeof(resp) + "' with type '" + typeof(resp2) + "' with opperation '<'",
@@ -224,6 +272,21 @@ func compareValues(o operationType, stack stack, stacklevel int) (bool, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return anyToBool(val), ArErr{}
}
}
}
if x, ok := resp2.(ArObject); ok {
if y, ok := x.obj["__LessThan__"]; ok {
val, err := runCall(
call{
y,
[]any{resp},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
@@ -287,6 +350,21 @@ func calcNegative(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return val, ArErr{}
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostSubtract__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -339,11 +417,26 @@ func calcDivide(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return val, ArErr{}
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostDivide__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
output = val return val, ArErr{}
return output, ArErr{}
} }
} }
return nil, ArErr{ return nil, ArErr{
@@ -459,11 +552,26 @@ func calcMul(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
output = val
return output, ArErr{}
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostMultiply__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
output = val return val, ArErr{}
return output, ArErr{}
} }
} }
return nil, ArErr{ return nil, ArErr{
@@ -508,7 +616,6 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -520,7 +627,6 @@ func calcOr(o operationType, stack stack, stacklevel int) (any, ArErr) {
stack, stack,
stacklevel+1, stacklevel+1,
) )
resp = ArValidToAny(resp)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
@@ -641,10 +747,25 @@ func notequals(a any, b any, o operationType, stack stack, stacklevel int) (bool
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return !anyToBool(val), ArErr{}
}
}
}
if x, ok := b.(ArObject); ok {
if y, ok := x.obj["__NotEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{a},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
return !anyToBool(val), ArErr{} return anyToBool(val), ArErr{}
} }
} }
return !reflect.DeepEqual(a, b), ArErr{} return !reflect.DeepEqual(a, b), ArErr{}
@@ -664,6 +785,21 @@ func equals(a any, b any, o operationType, stack stack, stacklevel int) (bool, A
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
return anyToBool(val), ArErr{}
}
}
}
if x, ok := b.(ArObject); ok {
if y, ok := x.obj["__GreaterThanEqual__"]; ok {
val, err := runCall(
call{
y,
[]any{a},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return false, err return false, err
} }
@@ -712,11 +848,27 @@ func calcMod(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
output = val
return output, ArErr{}
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostModulo__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
output = val return val, ArErr{}
return output, ArErr{}
} }
} }
return nil, ArErr{ return nil, ArErr{
@@ -764,11 +916,26 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
o.line, o.line,
o.path, o.path,
}, stack, stacklevel+1) }, stack, stacklevel+1)
if !err.EXISTS {
output = val
return output, ArErr{}
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostIntDivide__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS { if err.EXISTS {
return nil, err return nil, err
} }
output = val return val, ArErr{}
return output, ArErr{}
} }
} }
return nil, ArErr{ return nil, ArErr{
@@ -781,7 +948,7 @@ func calcIntDiv(o operationType, stack stack, stacklevel int) (any, ArErr) {
} }
} }
func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) { func calcPower(o operationType, stack stack, stacklevel int) (any, ArErr) {
resp, err := runVal( resp, err := runVal(
o.value1, o.value1,
stack, stack,
@@ -846,16 +1013,39 @@ func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
} }
output.Mul(output, calculated) output.Mul(output, calculated)
} }
return output, ArErr{}
/* } else if x, ok := resp.(ArObject); ok {
n1, _ := output.Float64() if y, ok := x.obj["__Power__"]; ok {
n2, _ := resp.(number).Float64() val, err := runCall(
output = newNumber().SetFloat64(math.Pow(n1, n2)) call{
if output == nil { y,
output = infinity []any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if !err.EXISTS {
return val, ArErr{}
}
}
}
if x, ok := resp.(ArObject); ok {
if y, ok := x.obj["__PostPower__"]; ok {
val, err := runCall(
call{
y,
[]any{output},
o.code,
o.line,
o.path,
}, stack, stacklevel+1)
if err.EXISTS {
return nil, err
}
return val, ArErr{}
}
} }
*/
} else {
return nil, ArErr{ return nil, ArErr{
"Runtime Error", "Runtime Error",
"Cannot calculate power of type '" + typeof(resp) + "'", "Cannot calculate power of type '" + typeof(resp) + "'",
@@ -865,8 +1055,6 @@ func calcPower(o operationType, stack stack, stacklevel int) (number, ArErr) {
true, true,
} }
} }
return output, ArErr{}
}
func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) { func runOperation(o operationType, stack stack, stacklevel int) (any, ArErr) {
switch o.operation { switch o.operation {

View File

@@ -74,6 +74,8 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
if colored { if colored {
output = append(output, "\x1b[0m") output = append(output, "\x1b[0m")
} }
case ArObject:
case anymap: case anymap:
if len(x) == 0 { if len(x) == 0 {
return "{}" return "{}"

View File

@@ -91,9 +91,16 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
} else if isString(code) { } else if isString(code) {
return parseString(code) return parseString(code)
} else if issquareroot(code) { } else if issquareroot(code) {
return parseSquareroot(code, index, codelines) resp, worked, err, i = parseSquareroot(code, index, codelines)
} else if isFactorial(code) { if worked {
return parseFactorial(code, index, codelines) return resp, worked, err, i
}
}
if isFactorial(code) {
resp, worked, err, i = parseFactorial(code, index, codelines)
if worked {
return resp, worked, err, i
}
} }
if isVariable(code) { if isVariable(code) {
return parseVariable(code) return parseVariable(code)
@@ -103,6 +110,8 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
if worked { if worked {
return resp, worked, err, i return resp, worked, err, i
} }
} else if isMap(code) {
resp, worked, err, i = parseMap(code, index, codelines)
} }
{ {
operation, worked, err, step := parseOperations(code, index, codelines) operation, worked, err, step := parseOperations(code, index, codelines)

View File

@@ -275,10 +275,9 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
case ArObject: case ArObject:
if _, ok := y.obj["__setindex__"]; ok { if _, ok := y.obj["__setindex__"]; ok {
callable := y.obj["__setindex__"] callable := y.obj["__setindex__"]
r := ArValidToAny(resp)
_, err := runCall(call{ _, err := runCall(call{
callable: callable, callable: callable,
args: []any{key, r}, args: []any{key, resp},
line: v.line, line: v.line,
path: v.path, path: v.path,
code: v.code, code: v.code,