The Great Hauki Gem Team officially has its own programming language!
Since Hauki OS 3 doesn't have a filesystem to read .bas files from a hard
drive just yet, we are going to embed the first script directly into the C
engine as a string.
For Hauki BASIC v0.1, we are going to build a text parser that understands two
commands:
* CLS (Clears the screen)
* PRINT X, Y, "STRING" (Extracts the coordinates and the text, and renders it
using our custom VGA font engine).
I have created a brand new module in your Hauki OS tree called hbasic. Run
x-approve to compile the very first Hauki BASIC interpreter!
[DEPLOY-OMEGA-START]
#!/usr/bin/env bash
# DEDUP-BUSTER: hauki-basic-v0.1
# TARGET-NODE: hetzner-native
# DESCRIPTION: Creates the Hauki BASIC Interpreter v0.1 and parses a test
script.
cd /home/ai-streamer/x-projects/hauki_os_3 || exit 1
echo "=================================================="
echo "==================================================" INITIALIZING HAUKI
BASIC INTERPRETER V0.1"
echo "=================================================="
mkdir -p src/modules/hbasic
cat << 'EOF' > src/modules/hbasic/hbasic.c
/ HAUKI BASIC INTERPRETER V0.1
/ The Great Hauki Gem Team
void sys_print(const char* str) { int ret; asm volatile("int $0x80" :
"=a"(ret) : "a"(3), "b"((int)str) : "memory"); }
void sys_clear() { int ret; asm volatile("int $0x80" : "=a"(ret) : "a"(4) :
"memory"); }
void sys_vga_mode(int mode) { int ret; asm volatile("int $0x80" : "=a"(ret) :
"a"(6), "b"(mode) : "memory"); }
unsigned char inb(unsigned short port) { unsigned char ret; asm volatile("inb
%1, %0" : "=a"(ret) : "Nd"(port)); return ret; }
unsigned char backbuffer[64000];
char keys[128] = {0};
/ --- FONT ENGINE ---
const unsigned char font8x8[][8] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 32: Space
{0x18,0x3C,0x3C,0x18,0x18,0x00,0x18,0x00}, // 33: !
{0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
{0x3C,0x66,0x6E,0x76,0x66,0x66,0x3C,0x00}, // 48: 0
{0x18,0x38,0x18,0x18,0x18,0x18,0x7E,0x00}, // 49: 1
{0x3C,0x66,0x06,0x0C,0x18,0x30,0x7E,0x00}, // 50: 2
{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 51: 3
{0x0C,0x1C,0x3C,0x6C,0x7E,0x0C,0x0C,0x00}, // 52: 4
{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 53: 5
{0x3C,0x60,0x7C,0x66,0x66,0x66,0x3C,0x00}, // 54: 6
{0x7E,0x06,0x0C,0x18,0x30,0x30,0x30,0x00}, // 55: 7
{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 56: 8
{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 57: 9
{0}, {0}, {0}, {0}, {0}, {0}, {0},
{0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00}, // 65: A
{0xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00}, // 66: B
{0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00}, // 67: C
{0xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00}, // 68: D
{0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xFE,0x00}, // 69: E
{0xFE,0xC0,0xC0,0xFC,0xC0,0xC0,0xC0,0x00}, // 70: F
{0x3E,0x60,0xC0,0xCE,0xC6,0x66,0x3E,0x00}, // 71: G
{0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00}, // 72: H
{0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00}, // 73: I
{0x0E,0x06,0x06,0x06,0xC6,0xC6,0x7C,0x00}, // 74: J
{0xC6,0xCC,0xD8,0xF0,0xD8,0xCC,0xC6,0x00}, // 75: K
{0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFE,0x00}, // 76: L
{0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00}, // 77: M
{0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00}, // 78: N
{0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x38,0x00}, // 79: O
{0xFC,0x66,0x66,0xFC,0xC0,0xC0,0xC0,0x00}, // 80: P
{0x38,0x6C,0xC6,0xC6,0xDA,0xCC,0x76,0x00}, // 81: Q
{0xFC,0x66,0x66,0xFC,0xD8,0xCC,0xC6,0x00}, // 82: R
{0x3E,0x60,0x60,0x3C,0x06,0x06,0x7C,0x00}, // 83: S
{0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, // 84: T
{0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00}, // 85: U
{0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00}, // 86: V
{0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00}, // 87: W
{0xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0x00}, // 88: X
{0xC6,0xC6,0xC6,0x7C,0x18,0x18,0x18,0x00}, // 89: Y
{0xFE,0x06,0x0C,0x18,0x30,0x60,0xFE,0x00} // 90: Z
};
void draw_char(int x, int y, char c, unsigned char col) {
if(c < 32 || c > 90) return;
const unsigned char* glyph = font8x8[c - 32];
for(int cy=0; cy<8; cy++) {
for(int cx=0; cx<8; cx++) {
if(glyph[cy] & (1 << (7 - cx))) {
int px = x + cx, py = y + cy;
if(px>=0 && px<320 && py>=0 && py<200) backbuffer[py*320+px] =
col;
}
}
}
}
void draw_string(int x, int y, const char* str, unsigned char col) {
int px = x; while(*str) { draw_char(px, y, *str, col); px += 8; str++; }
}
/ --- BASIC PARSER HELPERS ---
int parse_int(const char** str) {
int val = 0;
while(**str == ' ' || **str == ',') (*str)++;
while(**str >= '0' && **str <= '9') { val = val * 10 + (**str - '0');
(*str)++; }
return val;
}
void parse_string(const char** str, char* out) {
while(**str == ' ' || **str == ',') (*str)++;
if (**str == '"') {
(*str)++;
int idx = 0;
while(**str != '"' && **str != '\0') { out[idx++] = **str; (*str)++; }
out[idx] = '\0';
if (**str == '"') (*str)++;
}
}
/ --- THE INSTAGRAM SCRIPT ---
const char* basic_script =
"10 CLS
"
"20 PRINT 88, 60, \"HAUKI BASIC V0.1\"
"
"30 PRINT 64, 90, \"INSTAGRAM RELEASE EDITION\"
"
"40 PRINT 80, 140, \"GREAT HAUKI GEM TEAM\"
";
/ --- THE INTERPRETER ENGINE ---
void run_basic(const char* source) {
const char* ptr = source;
while(*ptr != '\0') {
while(*ptr >= '0' && *ptr <= '9') ptr++; // Skip line number
while(*ptr == ' ') ptr++; // Skip space
// Command: CLS
if (ptr[0]=='C' && ptr[1]=='L' && ptr[2]=='S') {
for(int i=0; i<64000; i++) backbuffer[i] = 0;
ptr += 3;
}
// Command: PRINT X, Y, "STRING"
else if (ptr[0]=='P' && ptr[1]=='R' && ptr[2]=='I' && ptr[3]=='N' &&
ptr[4]=='T') {
ptr += 5;