Benutzer-Werkzeuge

Webseiten-Werkzeuge


start

Dies ist eine alte Version des Dokuments!


// erlaubte Zeichen für Mini-BASIC
static int is_allowed_basic_char(char c) {
    if (c == ' ' || c == '.' || c == '"' || c == '=' || c == '+' || c == '-' ||
        c == '*' || c == '/' || c == '(' || c == ')' || c == '<' || c == '>' ||
        c == ',' ) return 1;

    if (c >= 'A' && c <= 'Z') return 1;
    if (c >= '0' && c <= '9') return 1;
    return 0;
}
// ===================== MINI BASIC (int-only) =====================

#define BASIC_MAX_LINES 64
#define BASIC_LINE_LEN  96

typedef struct {
    uint16 line_no;
    uint8  used;
    char   text[BASIC_LINE_LEN];
} BasicLine;

static BasicLine g_prog[BASIC_MAX_LINES];
static int g_vars[26]; // A..Z

static void basic_reset_program(void) {
    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        g_prog[i].used = 0;
        g_prog[i].line_no = 0;
        g_prog[i].text[0] = 0;
    }
}

static void basic_reset_vars(void) {
    for (int i = 0; i < 26; i++) g_vars[i] = 0;
}

static int is_space(char c) { return c == ' ' || c == '\t'; }

static char up(char c) {
    if (c >= 'a' && c <= 'z') return (char)(c - 'a' + 'A');
    return c;
}

static void skip_spaces(const char **p) {
    while (**p && is_space(**p)) (*p)++;
}

static int is_digit(char c) { return (c >= '0' && c <= '9'); }
static int is_alpha(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); }

static int starts_with_kw(const char *s, const char *kw) {
    // case-insensitive, kw muss "Wortgrenze" haben (Ende oder Space)
    int i = 0;
    while (kw[i]) {
        if (up(s[i]) != kw[i]) return 0;
        i++;
    }
    char next = s[i];
    return (next == 0 || is_space(next));
}

static uint16 parse_u16(const char **p) {
    skip_spaces(p);
    uint16 v = 0;
    while (is_digit(**p)) {
        v = (uint16)(v * 10 + (**p - '0'));
        (*p)++;
    }
    return v;
}

static int parse_int(const char **p) {
    skip_spaces(p);
    int sign = 1;
    if (**p == '+') { (*p)++; }
    else if (**p == '-') { sign = -1; (*p)++; }

    int v = 0;
    while (is_digit(**p)) {
        v = v * 10 + (**p - '0');
        (*p)++;
    }
    return v * sign;
}

static int find_line_index(uint16 line_no) {
    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        if (g_prog[i].used && g_prog[i].line_no == line_no) return i;
    }
    return -1;
}

static int find_free_slot(void) {
    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        if (!g_prog[i].used) return i;
    }
    return -1;
}

static int find_next_line_sorted(uint16 last_line, uint16 *out_line, int *out_idx) {
    int found = 0;
    uint16 best = 0xFFFF;
    int best_i = -1;

    for (int i = 0; i < BASIC_MAX_LINES; i++) {
        if (!g_prog[i].used) continue;
        uint16 ln = g_prog[i].line_no;
        if (ln > last_line && ln < best) {
            best = ln;
            best_i = i;
            found = 1;
        }
    }

    if (!found) return 0;
    *out_line = best;
    *out_idx = best_i;
    return 1;
}

static void basic_store_line(uint16 line_no, const char *rest) {
    // rest: nach der Zeilennummer (inkl. leading spaces)
    // Wenn rest leer -> löschen
    const char *p = rest;
    skip_spaces(&p);

    int idx = find_line_index(line_no);

    if (*p == 0) {
        if (idx >= 0) g_prog[idx].used = 0;
        return;
    }

    if (idx < 0) {
        idx = find_free_slot();
        if (idx < 0) {
            print_new_line();
            print_string("BASIC: OUT OF PROGRAM SPACE");
            return;
        }
        g_prog[idx].used = 1;
        g_prog[idx].line_no = line_no;
    }

    // copy text, uppercase keywords funktionieren trotzdem case-insensitive
    int j = 0;
    while (*p && j < BASIC_LINE_LEN - 1) {
        g_prog[idx].text[j++] = *p++;
    }
    g_prog[idx].text[j] = 0;
}

static void basic_list(void) {
    uint16 last = 0;
    uint16 ln;
    int idx;

    while (find_next_line_sorted(last, &ln, &idx)) {
        print_new_line();
        print_int((int)ln);
        print_string(" ");
        print_string(g_prog[idx].text);
        last = ln;
    }
}

static void basic_error(const char *msg) {
    print_new_line();
    print_string("BASIC ERROR: ");
    print_string((char*)msg);
}

// ---------- Expression parser (recursive descent) ----------
static int parse_expr(const char **p); // forward

static int parse_factor(const char **p) {
    skip_spaces(p);

    // unary
    if (**p == '+') { (*p)++; return parse_factor(p); }
    if (**p == '-') { (*p)++; return -parse_factor(p); }

    if (**p == '(') {
        (*p)++;
        int v = parse_expr(p);
        skip_spaces(p);
        if (**p == ')') (*p)++;
        else basic_error("MISSING )");
        return v;
    }

    // variable
    if (is_alpha(**p)) {
        char c = up(**p);
        (*p)++;
        if (c >= 'A' && c <= 'Z') return g_vars[c - 'A'];
        return 0;
    }

    // number
    if (is_digit(**p)) {
        return parse_int(p);
    }

    basic_error("BAD FACTOR");
    return 0;
}

static int parse_term(const char **p) {
    int v = parse_factor(p);
    for (;;) {
        skip_spaces(p);
        if (**p == '*') { (*p)++; v = v * parse_factor(p); }
        else if (**p == '/') {
            (*p)++;
            int d = parse_factor(p);
            if (d == 0) { basic_error("DIV BY ZERO"); return 0; }
            v = v / d;
        } else break;
    }
    return v;
}

static int parse_expr(const char **p) {
    int v = parse_term(p);
    for (;;) {
        skip_spaces(p);
        if (**p == '+') { (*p)++; v = v + parse_term(p); }
        else if (**p == '-') { (*p)++; v = v - parse_term(p); }
        else break;
    }
    return v;
}

static int parse_relop(const char **p, const char **out_op) {
    skip_spaces(p);
    // supported: =, <, >, <=, >=, <>
    if (**p == '=') { *out_op = "="; (*p)++; return 1; }
    if (**p == '<') {
        (*p)++;
        if (**p == '=') { *out_op = "<="; (*p)++; return 1; }
        if (**p == '>') { *out_op = "<>"; (*p)++; return 1; }
        *out_op = "<"; return 1;
    }
    if (**p == '>') {
        (*p)++;
        if (**p == '=') { *out_op = ">="; (*p)++; return 1; }
        *out_op = ">"; return 1;
    }
    return 0;
}

static int eval_relation(int a, int b, const char *op) {
    if (op[0] == '=' && op[1] == 0) return a == b;
    if (op[0] == '<' && op[1] == 0) return a < b;
    if (op[0] == '>' && op[1] == 0) return a > b;
    if (op[0] == '<' && op[1] == '=') return a <= b;
    if (op[0] == '>' && op[1] == '=') return a >= b;
    if (op[0] == '<' && op[1] == '>') return a != b;
    return 0;
}

// ---------- Statement execution ----------
static int basic_exec_stmt(const char *line, uint16 *pc_line /*in/out*/, int *stop /*out*/) {
    const char *p = line;
    skip_spaces(&p);

    if (*p == 0) return 1;

    // REM
    if (starts_with_kw(p, "REM")) return 1;

    // END
    if (starts_with_kw(p, "END")) { *stop = 1; return 1; }

    // PRINT
    if (starts_with_kw(p, "PRINT")) {
        p += 5;
        skip_spaces(&p);

        // PRINT "TEXT"
        if (*p == '"') {
            p++;
            print_new_line();
            while (*p && *p != '"') {
                print_char(*p++);
            }
            if (*p == '"') p++;
            return 1;
        }

        // PRINT expr
        int v = parse_expr(&p);
        print_new_line();
        print_int(v);
        return 1;
    }

    // LET (optional)
    if (starts_with_kw(p, "LET")) {
        p += 3;
        skip_spaces(&p);
    }

    // IF expr rel expr THEN line
    if (starts_with_kw(p, "IF")) {
        p += 2;
        int left = parse_expr(&p);

        const char *op = 0;
        if (!parse_relop(&p, &op)) { basic_error("IF NEEDS RELOP"); return 0; }

        int right = parse_expr(&p);

        skip_spaces(&p);
        if (!starts_with_kw(p, "THEN")) { basic_error("IF NEEDS THEN"); return 0; }
        p += 4;

        uint16 target = parse_u16(&p);
        if (target == 0) { basic_error("BAD THEN LINE"); return 0; }

        if (eval_relation(left, right, op)) {
            *pc_line = (uint16)(target - 1); // Trick: RUN loop nimmt "next > pc_line"
        }
        return 1;
    }

    // GOTO line
    if (starts_with_kw(p, "GOTO")) {
        p += 4;
        uint16 target = parse_u16(&p);
        if (target == 0) { basic_error("BAD GOTO LINE"); return 0; }
        *pc_line = (uint16)(target - 1);
        return 1;
    }

    // Assignment: A = expr
    if (is_alpha(*p)) {
        char vname = up(*p++);
        if (vname < 'A' || vname > 'Z') { basic_error("BAD VAR"); return 0; }
        skip_spaces(&p);
        if (*p != '=') { basic_error("EXPECTED ="); return 0; }
        p++;
        int value = parse_expr(&p);
        g_vars[vname - 'A'] = value;
        return 1;
    }

    basic_error("UNKNOWN STATEMENT");
    return 0;
}

static void basic_run(void) {
    uint16 pc = 0;         // last executed line_no (for sorted iteration)
    int stop = 0;

    // Start at "before" first line:
    pc = 0;

    while (!stop) {
        uint16 ln;
        int idx;
        if (!find_next_line_sorted(pc, &ln, &idx)) break;

        // execute
        uint16 pc_before = ln;
        uint16 pc_line = ln;
        basic_exec_stmt(g_prog[idx].text, &pc_line, &stop);

        // pc_line may be changed by GOTO/IF
        pc = pc_line;

        // normal case: move to next after current
        if (pc == pc_before) pc = ln;
    }
}

// ---------- REPL line handler ----------
static void basic_repl_line(const char *input) {
    const char *p = input;
    skip_spaces(&p);
    if (*p == 0) return;

    // line starts with number? -> program line
    if (is_digit(*p)) {
        uint16 ln = parse_u16(&p);
        basic_store_line(ln, p);
        return;
    }

    // Immediate commands
    if (starts_with_kw(p, "LIST")) { basic_list(); return; }
    if (starts_with_kw(p, "RUN"))  { basic_run(); return; }
    if (starts_with_kw(p, "NEW"))  { basic_reset_program(); basic_reset_vars(); print_new_line(); print_string("OK"); return; }

    // keep your old shell commands too:
    if (starts_with_kw(p, "HELP")) {
        print_new_line();
        print_string("Available commands:");
        print_new_line();
        print_string("  HELP   - Prints this help");
        print_new_line();
        print_string("  REBOOT - Reboot the system");
        print_new_line();
        print_string("  NEW    - Clear BASIC program + vars");
        print_new_line();
        print_string("  LIST   - List BASIC program");
        print_new_line();
        print_string("  RUN    - Run BASIC program");
        print_new_line();
        print_string("BASIC examples:");
        print_new_line();
        print_string("  10 A=1+2*3");
        print_new_line();
        print_string("  20 PRINT A");
        print_new_line();
        print_string("  30 IF A=7 THEN 50");
        print_new_line();
        print_string("  40 GOTO 20");
        print_new_line();
        print_string("  50 END");
        return;
    }

    if (starts_with_kw(p, "REBOOT")) { do_reboot(); return; }

    // Otherwise: treat as immediate BASIC statement (PRINT/LET/A=.../IF/GOTO/END)
    uint16 dummy = 0;
    int stop = 0;
    basic_exec_stmt(p, &dummy, &stop);
}

Hallo Besucher! Willkommen in diesem kleinen Wiki rund um IT. Vieles ist noch unvollständig, unstrukturiert oder vielleicht sogar falsch bzw. irreführend.

Du kannst Artikel gerne ergänzen oder verbessern. Gerne mit so vielen Links wie nötig. Bitte keine Werbelinks und nur selbst verfasste oder lizenzfreie Texte! Copyright beachten!

Fehlende Verlinkungen

Eine Liste von Seiten die noch erstellt werden müssen.

# ID Links
1xml3 : Show backlinks
2turn3 : Show backlinks
3a_stern_algorithmus3 : Show backlinks
4graylog2 : Show backlinks
5chef2 : Show backlinks
6bellman_ford_algorithmus2 : Show backlinks
7saslauthd2 : Show backlinks
8https2 : Show backlinks
9netzwerkkarte2 : Show backlinks
10rpc1 : Show backlinks
11prioritaetswarteschlange1 : Show backlinks
12vnc1 : Show backlinks
13sata1 : Show backlinks
14realmd1 : Show backlinks
15base641 : Show backlinks
16srtp1 : Show backlinks
17iscsitarget1 : Show backlinks
18kuerzeste_wege1 : Show backlinks
19hub1 : Show backlinks
20networkd1 : Show backlinks
21vmfs1 : Show backlinks
22iax21 : Show backlinks
23ice1 : Show backlinks
24ssd1 : Show backlinks
25graphentheorie1 : Show backlinks
26dnsrecon1 : Show backlinks
27wpa31 : Show backlinks
28ddos1 : Show backlinks
29courier1 : Show backlinks
30freepbx1 : Show backlinks
31webrtc1 : Show backlinks
32cuda1 : Show backlinks
33sips1 : Show backlinks
34unix1 : Show backlinks
35fierce1 : Show backlinks
36wifite1 : Show backlinks
37mailx1 : Show backlinks
383des1 : Show backlinks
39pcie1 : Show backlinks
40soundkarte1 : Show backlinks
41sendmail1 : Show backlinks
42oakley1 : Show backlinks
43nvme1 : Show backlinks
44tshark1 : Show backlinks
45pjsip1 : Show backlinks
46dnscat21 : Show backlinks
47playground:playground1 : Show backlinks
48breitensuche1 : Show backlinks
49creddump71 : Show backlinks
50sctp1 : Show backlinks
51eaphammer1 : Show backlinks
start.1765039070.txt.gz · Zuletzt geändert: 2025/12/06 17:37 von jango