add return and break

This commit is contained in:
Ugric committed 2022-06-29 00:49:49 +01:00
1 parent 10d1827eb7
commit af04585507
13 files changed
+241 -100

No files matched your search

File renamed without changes.
+3
View File
@@ -0,0 +1,3 @@
# make PI variable with PI to 1000 digits (may not be completely parsed)
PI = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989e-1000
+1 -1
View File
@@ -1 +1 @@
go build -o argon .
go build -o argon-lang/argon .
+1 -1
View File
@@ -1 +1 @@
go build -o argon .
go build -o argon-lang/argon .
+7 -4
View File
@@ -47,8 +47,11 @@ type setFunction struct {
line int
}
type functionSet struct {
name string
params []string
line int
type returnType struct {
val any
line int
}
type breakType struct {
line int
}
+8 -12
View File
@@ -1,12 +1,8 @@
import 'maths';
log('whats the radius of the circle?')
var radius = number(input('radius: '))
var area = PI times radius to the power of 2
var diameter = PI times radius
log()
log('the area of the circle is:', area)
log('the diameter of the circle is:', diameter)
i = 0
while yes [
i = i + 1
log(i)
if i > 10 [
break
]
]
+6 -2
View File
@@ -38,7 +38,7 @@ func importMod(path string) {
log.Fatal("Module not found: " + path + " (" + p + ")")
}
}
if xiny(path, imported) {
if xiny(p, imported) {
return
}
imported = append(imported, p)
@@ -51,5 +51,9 @@ func importMod(path string) {
func runStr(str string) [][]any {
translated := translate(str)
return run(translated)
ty, _, resp := run(translated, make(map[string]variableValue))
if ty != nil {
log.Fatal(ty, " at top level")
}
return resp
}
-1
View File
@@ -1 +0,0 @@
PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989
+111 -61
View File
@@ -8,21 +8,24 @@ import (
"strconv"
)
var runop func(codeseg any) (any, any)
var runop func(codeseg any, localvars map[string]variableValue) (any, any)
func init() {
runop = runprocess
}
func run(lines []any) [][]any {
func run(lines []any, localvars map[string]variableValue) (any, any, [][]any) {
output := ([][]any{})
for i := 0; i < len(lines); i++ {
if lines[i] != nil {
val, ty := runprocess(lines[i])
val, ty := runprocess(lines[i], localvars)
output = append(output, []any{val, ty})
if ty == "return" || ty == "break" {
return ty, val, output
}
}
}
return output
return nil, nil, output
}
func anyToArgon(x any) string {
@@ -46,95 +49,142 @@ func anyToArgon(x any) string {
}
}
func runprocess(codeseg any) (any, any) {
func runprocess(codeseg any, localvars map[string]variableValue) (any, any) {
switch codeseg.(type) {
case opperator:
return runOperator(codeseg.(opperator)), "opperator"
return runOperator(codeseg.(opperator), localvars), "opperator"
case variable:
myvar := vars[codeseg.(variable).variable]
myvar := localvars[codeseg.(variable).variable]
if myvar.EXISTS == nil {
myvar = vars[codeseg.(variable).variable]
}
if myvar.EXISTS != nil {
if myvar.TYPE != "func" && myvar.TYPE != "init_function" {
return myvar.VAL, "variable"
return myvar.VAL, "value"
} else {
return codeseg, "function"
return codeseg, "value"
}
}
log.Fatal("undecared variable " + codeseg.(variable).variable + " on line " + fmt.Sprint(codeseg.(variable).line+1))
case funcCallType:
return callFunc(codeseg.(funcCallType)), "return"
return callFunc(codeseg.(funcCallType), localvars), "value"
case whileLoop:
whileloop := codeseg.(whileLoop)
resp, _ := runop(whileloop.condition)
resp, _ := runop(whileloop.condition, localvars)
for boolean(resp) {
run(whileloop.code)
ty, val, _ := run(whileloop.code, localvars)
if ty == "break" {
break
} else if ty == "return" {
return val, "return"
}
}
case ifstatement:
iff := codeseg.(ifstatement)
resp, _ := runop(iff.condition)
resp, _ := runop(iff.condition, localvars)
if boolean(resp) {
run(iff.TRUE)
ty, val, _ := run(iff.TRUE, localvars)
return val, ty
} else {
run(iff.FALSE)
ty, val, _ := run(iff.FALSE, localvars)
return val, ty
}
return nil, nil
case importType:
importMod((codeseg.(importType).path).(string))
return nil, nil
case setVariable:
setVariableVal(codeseg.(setVariable))
setVariableVal(codeseg.(setVariable), localvars)
return nil, nil
case setFunction:
setFunctionVal(codeseg.(setFunction))
setFunctionVal(codeseg.(setFunction), localvars)
return nil, nil
case returnType:
val, worked := runop(codeseg.(returnType).val, localvars)
if worked == nil {
log.Fatal("return statement must return a value on line " + fmt.Sprint(codeseg.(returnType).line+1))
}
return val, "return"
case breakType:
return nil, "break"
}
return codeseg, "value"
}
func callFunc(call funcCallType) any {
if vars[call.name].EXISTS == nil {
func callFunc(call funcCallType, localvars map[string]variableValue) any {
variables := localvars
if variables[call.name].EXISTS == nil {
variables = vars
}
if variables[call.name].EXISTS == nil {
log.Fatal("undecared function '" + call.name + "' on line " + fmt.Sprint(call.line+1))
}
callable := call
for vars[callable.name].TYPE != "func" && vars[callable.name].TYPE != "init_function" && fmt.Sprint(reflect.TypeOf(vars[callable.name].VAL)) == "main.variable" {
callable = funcCallType{name: vars[callable.name].VAL.(variable).variable, args: callable.args, line: callable.line}
for variables[callable.name].TYPE != "func" && vars[callable.name].TYPE != "init_function" && fmt.Sprint(reflect.TypeOf(variables[callable.name].VAL)) == "main.variable" {
callable = funcCallType{name: variables[callable.name].VAL.(variable).variable, args: callable.args, line: callable.line}
}
if vars[callable.name].TYPE != "func" && vars[callable.name].TYPE != "init_function" {
if variables[callable.name].TYPE != "func" && variables[callable.name].TYPE != "init_function" {
log.Fatal("'" + call.name + "' is not a function on line " + fmt.Sprint(call.line+1))
}
argvals := []any{}
for i := 0; i < len(callable.args); i++ {
resp, _ := runprocess(callable.args[i])
argvals = append(argvals, resp)
}
if vars[callable.name].FUNC {
argvals := []any{}
for i := 0; i < len(callable.args); i++ {
resp, _ := runprocess(callable.args[i], localvars)
argvals = append(argvals, resp)
}
return vars[callable.name].VAL.(func(...any) any)(argvals...)
} else {
run(vars[callable.name].VAL.(setFunction).code)
return nil
argvars := make(map[string]variableValue)
for i := 0; i < len(callable.args); i++ {
resp, _ := runprocess(callable.args[i], localvars)
name := variables[callable.name].VAL.(setFunction).args[i]
argvars[name] = variableValue{
VAL: resp,
TYPE: "var",
EXISTS: true,
FUNC: false,
}
}
ty, val, _ := run(vars[callable.name].VAL.(setFunction).code, argvars)
if ty != "return" && ty != nil {
log.Fatal(ty, " is not allowed in top level of function on line ", (callable.line + 1))
}
return val
}
}
func setVariableVal(x setVariable) {
variable := vars[x.variable]
if variable.EXISTS == nil {
resp, _ := runop(x.value)
vars[x.variable] = variableValue{
func setVariableVal(x setVariable, localvars map[string]variableValue) {
variable := localvars
if variable[x.variable].EXISTS == nil {
variable = vars
}
vari := variable[x.variable]
if variable[x.variable].EXISTS == nil {
resp, _ := runop(x.value, localvars)
variable[x.variable] = variableValue{
TYPE: x.TYPE,
EXISTS: true,
VAL: resp,
FUNC: false,
}
} else if variable.TYPE == "var" {
variable.VAL, _ = runop(x.value)
} else if variable[x.variable].TYPE == "var" {
val, _ := runop(x.value, localvars)
variable[x.variable] = variableValue{
TYPE: x.TYPE,
EXISTS: variable[x.variable].EXISTS,
VAL: val,
FUNC: variable[x.variable].FUNC,
}
} else {
log.Fatal("cannot edit " + variable.TYPE + " variable on line " + fmt.Sprint(x.line+1))
log.Fatal("cannot edit " + vari.TYPE + " variable on line " + fmt.Sprint(x.line+1))
}
}
func setFunctionVal(x setFunction) {
variable := vars[x.name]
func setFunctionVal(x setFunction, localvars map[string]variableValue) {
variable := localvars[x.name]
if variable.EXISTS == nil {
variable = vars[x.name]
}
if vars[x.name].EXISTS == nil {
vars[x.name] = variableValue{
TYPE: "func",
@@ -204,12 +254,12 @@ func number(x any) float64 {
}
}
func runOperator(opperation opperator) any {
func runOperator(opperation opperator, localvars map[string]variableValue) any {
var output any
for i := 0; i < len(opperation.vals); i++ {
switch opperation.t {
case 0:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
@@ -221,118 +271,118 @@ func runOperator(opperation opperator) any {
}
}
case 1:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if boolean(x) {
output = x
break
}
case 2:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = xiny(output, x.([]any))
}
case 3:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = !xiny(output, x.([]interface{}))
}
case 4:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) <= number(x))
}
case 5:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) >= number(x))
}
case 6:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) < number(x))
}
case 7:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) > number(x))
}
case 8:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (output != x)
}
case 9:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (output == x)
}
case 10:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) - number(x))
}
case 11:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = dynamicAdd(output, x)
}
case 12:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) * number(x))
}
case 13:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = math.Floor(number(output) / number(x))
}
case 14:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = math.Mod(number(output), number(x))
}
case 15:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = (number(output) / number(x))
}
case 16:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
output = math.Pow(number(output), 1/number(x))
}
case 17:
x, _ := runop(opperation.vals[i])
x, _ := runop(opperation.vals[i], localvars)
if output == nil {
output = x
} else {
+6 -4
View File
@@ -13,10 +13,12 @@ func shell() {
} else {
tempstr = ArgonInput("... ").(string) + "\n"
}
if openCompile.MatchString(tempstr) {
indent--
} else if closeCompile.MatchString(tempstr) {
indent++
if !switchCloseCompile.MatchString(tempstr) {
if openCompile.MatchString(tempstr) {
indent--
} else if closeCompile.MatchString(tempstr) {
indent++
}
}
temp += tempstr
if indent >= 0 {
+6 -4
View File
@@ -1,11 +1,13 @@
completed:
-
- while loops
- subs (functions)
- add return to functions
- add break
incompleted:
- books (objects)
- subs (functions)
- items (arrays)
- while loops
- add else if to if statments
- add return to functions
- add try catch
- add continue
- allow functions parameters to be passed in
+80 -10
View File
@@ -25,7 +25,8 @@ var functionCompile = makeRegex("( *)" + variableOnly + "\\(" + anyAndNewline +
var variableTextCompile = makeRegex("( *)" + variableOnly + "( *)")
var variableonlyCompile = makeRegex(variableOnly)
var setVariableCompile = makeRegex("( *)(((const|var) (" + variableOnly + "( *))=( *).+)|(( *)" + variableOnly + "( *))(( *)=( *).+))( *)")
var returnStatementCompile = makeRegex("( *)(return( )+" + anyAndNewline + "*)( *)")
var returnStatementCompile = makeRegex("( *)(return(( )+" + anyAndNewline + "*)?)( *)")
var breakStatementCompile = makeRegex("( *)break( *)")
var skipCompile = makeRegex("( *)(#(.*))?")
var processfunc func(codeseg code) (interface{}, bool)
var linefunc func(i int, codearray []code) (interface{}, int)
@@ -145,6 +146,61 @@ func getValuesFromCommas(str string, line int) ([]any, bool) {
return output, true
}
// make a function that converts backslashes in a string to their correct character
// e.g. "\n" -> newline
// e.g. "\t" -> tab
// e.g. "\r" -> carriage return
// e.g. "\b" -> backspace
// e.g. "\f" -> formfeed
// e.g. "\a" -> alert
// e.g. "\v" -> vertical tab
// e.g. "\0" -> null
// e.g. "\'" -> single quote
// e.g. "\"" -> double quote
// e.g. "\\" -> backslash
// e.g. unicode characters like \u00A0 -> unicode
func unescape(str string) string {
output := []byte{}
stringlen := len(str)
for i := 0; i < stringlen; i++ {
if str[i] == 92 {
if i+1 < stringlen {
i++
switch str[i] {
case 110:
output = append(output, 10)
case 116:
output = append(output, 9)
case 114:
output = append(output, 13)
case 98:
output = append(output, 8)
case 102:
output = append(output, 12)
case 118:
output = append(output, 11)
case 120:
output = append(output, 0)
case 34:
output = append(output, 34)
case 39:
output = append(output, 39)
case 92:
output = append(output, 92)
case 117:
if i+4 < stringlen {
i += 4
output = append(output, byte(int(str[i])*16*16*16+int(str[i+1])*16*16+int(str[i+2])*16+int(str[i+3])))
}
}
}
} else {
output = append(output, str[i])
}
}
return string(output[:])
}
func getParamNames(str string, line int) []string {
output := []string{}
temp := []byte{}
@@ -203,12 +259,6 @@ func split_by_semicolon_and_newline(str string) []code {
temp = append(temp, str[i])
}
}
finaloutput := []code{}
for i := 0; i < len(output); i++ {
if strings.Trim(output[i].code, " ") != "" {
finaloutput = append(finaloutput, output[i])
}
}
output = append(output, code{code: string(temp[:]), line: line})
return output
}
@@ -222,12 +272,12 @@ var getCodeInIndent = func(i int, codearray []code, isIf bool) ([]code, int) {
})
i++
for {
if closeCompile.MatchString(codearray[i].code) || (isIf && (elseCompile.MatchString(codearray[i].code) || elseifCompile.MatchString(codearray[i].code))) {
if (closeCompile.MatchString(codearray[i].code) && !switchCloseCompile.MatchString(codearray[i].code)) || (isIf && (elseCompile.MatchString(codearray[i].code) || elseifCompile.MatchString(codearray[i].code))) {
indent++
if indent > 0 {
break
}
} else if openCompile.MatchString(codearray[i].code) {
} else if openCompile.MatchString(codearray[i].code) && !switchCloseCompile.MatchString(codearray[i].code) {
indent--
}
result = append(result, codearray[i])
@@ -276,7 +326,7 @@ var translateprocess = func(codeseg code) (interface{}, bool) {
}
}
if stringCompile.MatchString(codeseg.code) {
return (stringencode(codeseg.code)), true
return unescape(stringencode(codeseg.code)), true
} else if functionCompile.MatchString(codeseg.code) {
str := strings.Trim(codeseg.code, " ")
bracketsplit := strings.SplitN(str, "(", 2)
@@ -315,6 +365,26 @@ var translateprocess = func(codeseg code) (interface{}, bool) {
var translateline = func(i int, codearray []code) (interface{}, int) {
codeseg := codearray[i]
if returnStatementCompile.MatchString(codeseg.code) {
var val any = strings.Trim(codeseg.code, " ")[6:]
if val != "" {
respval, worked := translateprocess(code{code: val.(string), line: codeseg.line})
if !worked {
log.Fatal("invalid value on line ", codeseg.line+1)
}
val = respval
} else {
val = nil
}
return returnType{
val: val,
line: codeseg.line,
}, i + 1
} else if breakStatementCompile.MatchString(codeseg.code) {
return breakType{
line: codeseg.line,
}, i + 1
}
resp, worked := translateprocess(codeseg)
if worked {
return resp, i + 1
+12
View File
@@ -64,4 +64,16 @@ func init() {
VAL: ArgonLicense,
FUNC: true,
}
vars["exec"] = variableValue{
TYPE: "init_function",
EXISTS: true,
VAL: exec,
FUNC: true,
}
vars["eval"] = variableValue{
TYPE: "init_function",
EXISTS: true,
VAL: eval,
FUNC: true,
}
}