fix brainfuck, allow multiplying array by int, and fix incorrect error message in ord

This commit is contained in:
2025-02-19 02:31:32 +00:00
parent c75be1c8ed
commit 8f51b24c7c
6 changed files with 81 additions and 37 deletions

9
server_test/app.ar Normal file
View File

@@ -0,0 +1,9 @@
import "http.ar" as http
let server = http.server()
let home(req,res) = do
res.send("hello world")
server.get("/", home)
server.run()

View File

@@ -61,6 +61,29 @@ func ArArray(arr []any) ArObject {
return nil, ArErr{}
},
}
val.obj["__Multiply__"] = builtinFunc{
"__Multiply__",
func(a ...any) (any, ArErr) {
if len(a) != 1 {
return nil, ArErr{"Type Error", "expected 1 argument, got " + fmt.Sprint(len(a)), 0, "", "", true}
}
if typeof(a[0]) != "number" {
return nil, ArErr{"Type Error", "cannot multiply array by " + typeof(a[0]), 0, "", "", true}
}
n := a[0].(number)
if !n.IsInt() {
return nil, ArErr{"Value Error", "cannot multiply array by float", 0, "", "", true}
}
if n.Sign() < 0 {
return nil, ArErr{"Value Error", "cannot multiply array by negative number", 0, "", "", true}
}
size := int(n.Num().Int64())
retval := make([]any, 0, len(arr)*size)
for i := 0; i < size; i++ {
retval = append(retval, arr...)
}
return ArArray(retval), ArErr{}
}}
val.obj["__getindex__"] = builtinFunc{
"__getindex__",
func(a ...any) (any, ArErr) {
@@ -474,7 +497,7 @@ func ArArray(arr []any) ArObject {
}
if len(arr) == 0 {
return nil, ArErr{
TYPE: "ValueError",
TYPE: "Value Error",
message: "array is empty",
EXISTS: true,
}

View File

@@ -53,7 +53,7 @@ func ArByte(Byte byte) ArObject {
n := x.Num().Int64()
if n > 255 || n < 0 {
return nil, ArErr{
TYPE: "ValueError",
TYPE: "Value Error",
message: "expected number between 0 and 255, got " + fmt.Sprint(floor(x).Num().Int64()),
EXISTS: true,
}
@@ -62,7 +62,7 @@ func ArByte(Byte byte) ArObject {
case string:
if len(x) != 1 {
return nil, ArErr{
TYPE: "ValueError",
TYPE: "Value Error",
message: "expected string of length 1, got " + fmt.Sprint(len(x)),
EXISTS: true,
}

View File

@@ -267,7 +267,7 @@ func makeGlobal() ArObject {
switch x := a[0].(type) {
case string:
if len(x) != 1 {
return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(a)), EXISTS: true}
return nil, ArErr{TYPE: "ord", message: "ord takes a string with only one character, got " + fmt.Sprint(len(x)), EXISTS: true}
}
return floor(newNumber().SetInt64(int64([]rune(x)[0]))), ArErr{}
}

View File

@@ -629,10 +629,10 @@ func ArString(str string) ArObject {
}
n := a[0].(number)
if !n.IsInt() {
return nil, ArErr{"ValueError", "cannot multiply string by float", 0, "", "", true}
return nil, ArErr{"Value Error", "cannot multiply string by float", 0, "", "", true}
}
if n.Sign() < 0 {
return nil, ArErr{"ValueError", "cannot multiply string by negative number", 0, "", "", true}
return nil, ArErr{"Value Error", "cannot multiply string by negative number", 0, "", "", true}
}
return strings.Repeat(str, int(n.Num().Int64())), ArErr{}
}}

View File

@@ -1,33 +1,45 @@
let interpret(code) = do
memory = map()
let brainfuck(INPUT) = do
memory = [0] * 30*1000
pointer = 0
code_ptr = 0
loops = []
output = ""
i = 0
while (i < INPUT.length) do
if (INPUT[i] == ">") do
pointer += 1
else if (INPUT[i] == "<") do
pointer -= 1
else if (INPUT[i] == "+") do
memory[pointer] += 1
else if (INPUT[i] == "-") do
memory[pointer] -= 1
else if (INPUT[i] == ".") do
output += chr(memory[pointer])
else if (INPUT[i] == ",") do
memory[pointer] = ord(input())
else if (INPUT[i] == "[") do
if (memory[pointer] == 0) do
count = 1
while (count > 0) do
i += 1
if (INPUT[i] == "[") do
count += 1
else if (INPUT[i] == "]") do
count -= 1
else if (INPUT[i] == "]") do
if (memory[pointer] != 0) do
count = 1
while (count > 0) do
i -= 1
if (INPUT[i] == "]") do
count += 1
else if (INPUT[i] == "[") do
count -= 1
else do
pass
i += 1
term.print(memory)
return output
while (code_ptr < code.length) do
command = code[code_ptr]
if (command == '>') pointer = pointer + 1
else if (command == '<') pointer = pointer - 1
else if (command == '+') do
if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] + 1
else if (command == '-') do
if (pointer not in memory) memory[pointer] = 0
memory[pointer] = memory[pointer] - 1
else if (command == '.') term.log((memory.get(pointer, 0)))
else if (command == ',') memory[pointer] = ord(input())
else if (command == '[') do
if (memory.get(pointer, 0) == 0) do
loop_depth = 1
while (loop_depth > 0) do
code_ptr = code_ptr + 1
if (code[code_ptr] == '[') loop_depth = loop_depth + 1
else if (code[code_ptr] == ']') loop_depth = loop_depth - 1
else loops.append(code_ptr)
else if (command == ']') do
if (memory.get(pointer, 0) != 0) code_ptr = loops[-1]
else loops.pop()
code_ptr = code_ptr + 1
interpret('>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.')
term.time("brainfuck")
term.plain.oneLine(brainfuck(input()))
term.timeEnd("brainfuck")