Skip to content

Commit 4f7de4c

Browse files
committed
hehehe
1 parent 8d3c971 commit 4f7de4c

11 files changed

+325
-14
lines changed

bench.sh

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
INT=${1:-./kissfuck}
4+
5+
# runs time benchmark
6+
echo "This is benchmake for $INT virtual machine! :p"
7+
echo " You can pass any other vm as first argument! "
8+
echo " time utility required to be installed! "
9+
echo "----------------------------------------------"
10+
11+
for fl in ./tests/*; do
12+
echo "-------------------------------------------"
13+
echo "running for a file $fl"
14+
echo " "
15+
sudo chrt -f 99 time -f "\n\nelapsed=%E cpu=%P returns=%x" $INT $fl
16+
done

benchmark/linux.txt

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
This is benchmake for ./kissfuck virtual machine! :p
2+
You can pass any other vm as first argument!
3+
perf utility required to be installed!
4+
----------------------------------------------
5+
-------------------------------------------
6+
running for a file ./tests/addition.bfk
7+
8+
EEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAEEEEEEEEEEEEEEEEEEEEEEE
9+
10+
elapsed=0:00.00 cpu=50% returns=0
11+
-------------------------------------------
12+
running for a file ./tests/beaver.txt
13+
14+
OK
15+
16+
17+
elapsed=0:00.11 cpu=99% returns=0
18+
-------------------------------------------
19+
running for a file ./tests/bench.txt
20+
21+
OK
22+
23+
elapsed=0:00.01 cpu=83% returns=0
24+
-------------------------------------------
25+
running for a file ./tests/counter.txt
26+
27+
OK
28+
29+
30+
elapsed=0:16.28 cpu=95% returns=0
31+
-------------------------------------------
32+
running for a file ./tests/loop.bfk
33+
34+
TSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+
35+
36+
elapsed=0:00.00 cpu=100% returns=0
37+
-------------------------------------------
38+
running for a file ./tests/NUNZ.bfk
39+
40+
222222OK
41+
42+
elapsed=0:00.00 cpu=0% returns=0

benchmark/windows-trough-wine.txt

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
This is benchmake for wine ./kissfuck.exe virtual machine! :p
2+
You can pass any other vm as first argument!
3+
perf utility required to be installed!
4+
----------------------------------------------
5+
-------------------------------------------
6+
running for a file ./tests/addition.bfk
7+
8+
EEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAEEEEEEEEEEEEEEEEEEEEEEE
9+
10+
elapsed=0:12.46 cpu=1% returns=0
11+
-------------------------------------------
12+
running for a file ./tests/beaver.txt
13+
14+
OK
15+
16+
elapsed=0:00.30 cpu=41% returns=0
17+
-------------------------------------------
18+
running for a file ./tests/bench.txt
19+
20+
OK
21+
22+
elapsed=0:00.18 cpu=64% returns=0
23+
-------------------------------------------
24+
running for a file ./tests/counter.txt
25+
26+
OK
27+
28+
29+
elapsed=0:13.95 cpu=0% returns=0
30+
-------------------------------------------
31+
running for a file ./tests/loop.bfk
32+
33+
TSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+
34+
35+
elapsed=0:00.17 cpu=68% returns=0
36+
-------------------------------------------
37+
running for a file ./tests/NUNZ.bfk
38+
39+
222222OK
40+
41+
elapsed=0:00.19 cpu=62% returns=0

kisscomp.c

+27-6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ static inline void pushbc2(struct compstate* x, enum bytecode b, uint16_t v) {
6262
x->instp += 2;
6363
};
6464

65+
// does some loop optimisations :p
66+
static void loopoptimisation(struct compstate* x, uint16_t fst, uint16_t sec) {
67+
uint16_t ipos = fst + sizeof(uint16_t) + 1;
68+
if (sec == ipos) { // this is an infinite loop :O
69+
x->instp -= 3; // remove BC_JPNZ
70+
*(uint16_t*)(x->bytecode + fst + 1) = sec + 1;
71+
x->bytecode[x->instp++] = BC_HALT;
72+
assert(x->instp == sec + 1); // for some reason...
73+
}
74+
if (sec == (ipos + 2) && x->bytecode[ipos] == BC_ADD) {
75+
// [-]and [+] optimisation
76+
x->instp -= 3 + 2 + 3; // remove loop fully
77+
pushbc1(x, BC_SET, 0); // heheboi
78+
} else if (sec == (ipos + 3) && x->bytecode[ipos] == BC_NEXT) {
79+
// [>] and [<] optimisation :D
80+
uint16_t v = *(uint16_t*)(x->bytecode + ipos + 1); // read arg
81+
x->instp -= 3 + 3 + 3; // remove loop fully
82+
pushbc2(x, BC_NUNZ, v); // next until not zero :p
83+
}
84+
}
85+
6586
// links jumps instructions to each other (on instruction below each other)
6687
static int finallize_jumppair(struct compstate* x, uint16_t f, uint16_t s) {
6788
// next instructions after JPZ and JPNZ instructions
@@ -70,17 +91,20 @@ static int finallize_jumppair(struct compstate* x, uint16_t f, uint16_t s) {
7091
// set jump distanations
7192
*(uint16_t*)(x->bytecode + f + 1) = end;
7293
*(uint16_t*)(x->bytecode + s + 1) = start;
94+
95+
// do some optimisations
96+
loopoptimisation(x, f, s);
7397
return ERR_OK;
7498
}
7599

76100
// tries to finnalize jumppair (returns 1 on success)
77101
static int trytofinnalize(struct compstate* x) {
78-
uint16_t* start = &x->jmptbl[x->jmptblpos][1];
79-
uint16_t* end = &x->jmptbl[x->jmptblpos][0];
102+
uint16_t* start = &x->jmptbl[x->jmptblpos][0];
103+
uint16_t* end = &x->jmptbl[x->jmptblpos][1];
80104

81105
if (*start && *end) {
82106
// table can be finnalized!
83-
assert(finallize_jumppair(x, *start, *end) == ERR_OK);
107+
finallize_jumppair(x, *start, *end);
84108
*start = 0;
85109
*end = 0;
86110
return 1;
@@ -221,9 +245,6 @@ int loadcode(struct kissfuck* kf, const char* filename) {
221245
case TOKEN_POOL :
222246
newcode(x, BC_JPNZ); // close other bytecodes
223247
addjumpend(x); // save code position to the jumptable
224-
// instruction body will be rewrited later...
225-
pushbc2(x, BC_JPNZ, 0);
226-
227248
break;
228249
default:
229250
compiler_message(x, "impossible!");

kissdbg.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
#include <stddef.h>
1515

1616
static const char* bcname[] = {
17-
"HALT", "SET ", "ADD ", "IN ", "OUT ", "NEXT", "JPZ ", "JPNZ"
17+
"HALT", "SET ", "ADD ", "IN ", "OUT ",
18+
"NEXT", "JPZ ", "JPNZ", "COPY", "NUNZ"
1819
};
1920

2021
/*
@@ -44,7 +45,7 @@ void printbytecode (struct kissfuck* x, int i, int arg) {
4445
if (l >= 0) fprintf(stderr, "(0x%05X) L%03i\t: ", i, l);
4546
else fprintf(stderr, "(0x%05X) \t: ", i);
4647
enum bytecode bc = x->bytecode[i];
47-
if (bc <= 7) fprintf(stderr, bcname[bc]);
48+
if (bc <= 9) fprintf(stderr, bcname[bc]);
4849
else {
4950
int v = bc;
5051
fprintf(stderr, "?%03i", v);
@@ -76,7 +77,7 @@ void printbytecode (struct kissfuck* x, int i, int arg) {
7677

7778
static void printunkn(struct kissfuck* x, int i) {
7879
int l = find_label(i);
79-
if (l >= 0) fprintf(stderr, "L%03i\t: ", l);
80+
if (l >= 9) fprintf(stderr, "L%03i\t: ", l);
8081
else fprintf(stderr, " \t: ");
8182
int bc = x->bytecode[i];
8283
fprintf(stderr, "?%03i", bc);
@@ -97,7 +98,7 @@ int dumpcode(struct kissfuck* x) {
9798
if (ch == BC_JPZ || ch == BC_JPNZ) {
9899
printbytecode(x, i, 3);
99100
i += 3;
100-
} else if (ch == BC_NEXT) {
101+
} else if (ch == BC_NEXT || ch == BC_NUNZ) {
101102
printbytecode(x, i, 2);
102103
i += 3;
103104
} else if (ch == BC_HALT) {

kissfuck.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@
5555
#define VALID_CHAR(A) (VALID_TOKEN(A) || CHAR_COMM(A))
5656

5757
/*
58-
* BYTECODE section
58+
* BYTECODE
5959
*/
6060

6161
enum bytecode {
6262
// bc = id // (args in bytes count) desc
63+
// LOW LEVEL CONSTANT OPERATIONS
6364
BC_HALT = 0, // (0) stops execution
6465
BC_SET = 1, // (1) set current cell value == '[-]'
6566
BC_ADD = 2, // (1) adds constant number
@@ -68,6 +69,10 @@ enum bytecode {
6869
BC_NEXT = 5, // (2) goes to next N cell
6970
BC_JPZ = 6, // (2) jump if zero forward
7071
BC_JPNZ = 7, // (2) jump if not zero backward
72+
73+
// HIGH LEVEL OPERATIONS
74+
BC_COPY = 8, // (1) copies value from curr cell to next N cell
75+
BC_NUNZ = 9, // (2) jump next N cells until not zero == '[>]'
7176
};
7277

7378
#define BC_OPTIMIZABLE(A) (A < BC_JPZ)

kissvm.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ int execcode (struct kissfuck* const x) {
4343

4444
while (works) {
4545
if (unlikely(has_signal)) {
46-
fprintf(stderr, "[vm] : INTERRUPTED!\n");
46+
fprintf(stderr, "\n[vm] : INTERRUPTED!\n");
4747
break;
4848
};
4949
uint8_t C = reads();
@@ -82,6 +82,10 @@ int execcode (struct kissfuck* const x) {
8282
if (cell()) IP = readl();
8383
else IP += 2; // skip readed value only if we skips jump
8484
break;
85+
case BC_NUNZ:
86+
while (cell()) SP += readl();
87+
IP += 2;
88+
break;
8589
default :
8690
// you will never get here!
8791
unreachable();

test.bfk

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
# CONDITION AND LOOP TEST
1+
# Next Until Not Zero Test
22

3+
>>>>>>
34
+++++++++++++++++++++++++
45
+++++++++++++++++++++++++
5-
.........................
6+
...
7+
<<+<+
8+
[>]
9+
>
10+
...
11+
12+
#print OK
13+
-[--->+<]>------.----.

testanything.sh

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
INT=${1:-./kissfuck}
4+
5+
6+
for fl in ./tests/*; do
7+
echo -e "\n-------------------------------------------"
8+
echo "running for a file $fl"
9+
echo " "
10+
11+
$INT $fl || exit -1
12+
done
13+
14+
echo -e "\nAll tests passed!"
15+
exit 0

tests/NUNZ.bfk

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Next Until Not Zero Test
2+
3+
>>>>>>
4+
+++++++++++++++++++++++++
5+
+++++++++++++++++++++++++
6+
...
7+
<<+<+
8+
[>]
9+
>
10+
...
11+
12+
#print OK
13+
>-[--->+<]>------.----.

0 commit comments

Comments
 (0)