mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
var factorialCompiled = makeRegex(`( *)(.|\n)+\!( *)`)
|
|
|
|
type factorial struct {
|
|
value any
|
|
code string
|
|
line int
|
|
path string
|
|
}
|
|
|
|
func parseFactorial(code UNPARSEcode, index int, codeline []UNPARSEcode) (factorial, bool, ArErr, int) {
|
|
trim := strings.TrimSpace(code.code)
|
|
trim = trim[:len(trim)-1]
|
|
val, success, err, i := translateVal(UNPARSEcode{code: trim, realcode: code.realcode, line: code.line, path: code.path}, index, codeline, 0)
|
|
if !success {
|
|
return factorial{}, false, err, i
|
|
}
|
|
|
|
return factorial{val, code.code, code.line, code.path}, success, ArErr{}, i
|
|
}
|
|
|
|
func isFactorial(code UNPARSEcode) bool {
|
|
return factorialCompiled.MatchString(code.code)
|
|
}
|
|
|
|
func runFactorial(f factorial, stack stack, stacklevel int) (any, ArErr) {
|
|
val, err := runVal(f.value, stack, stacklevel+1)
|
|
if err.EXISTS {
|
|
return nil, err
|
|
}
|
|
switch val := val.(type) {
|
|
case ArObject:
|
|
if callable, ok := val.obj["__factorial__"]; ok {
|
|
return runCall(call{
|
|
Callable: callable,
|
|
Args: []any{},
|
|
Code: f.code,
|
|
Line: f.line,
|
|
Path: f.path,
|
|
}, stack, stacklevel)
|
|
}
|
|
}
|
|
return nil, ArErr{
|
|
TYPE: "TypeError",
|
|
message: "factorial not defined for type",
|
|
EXISTS: true,
|
|
}
|
|
}
|