/
freewaffle
/
wl
Обзор
Документация
Войти
/
freewaffle
/
wl
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/main.c
198 строк
5 KB
freewaffle
init commit
18 янв 2026, 22:24
18 янв 2026, 22:24
9e10e8a
Код
Авторство
О чём код?
#include <stdio.h> #include <stdlib.h> #include <string.h> #define ALLOC_STRUCT(STRUCT) (STRUCT*)calloc(1, sizeof(STRUCT)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define WL_DEBUG_PRINTING #ifdef WL_DEBUG_PRINTING # define DBG_PRINTF(...) printf(__VA_ARGS__) #else # define DBG_PRINTF() #endif typedef enum { wl_InstrPushNum, wl_InstrAdd, wl_InstrMul, } wl_Instruction; typedef enum { wl_TokenNumber, wl_TokenPlus, wl_TokenMinus, wl_TokenMul, wl_TokenDiv, wl_TokenParenOpen, wl_TokenParenClose, } wl_TokenType; typedef union { float num; // other types } wl_Value; typedef struct { wl_TokenType type; wl_Value value; } wl_Token; const char *wl_get_token_name(wl_Token *token) { switch (token->type) { case wl_TokenNumber: return "number"; case wl_TokenPlus: return "plus"; case wl_TokenMinus: return "minus"; case wl_TokenMul: return "mul"; case wl_TokenDiv: return "div"; default: return "unknown"; } } // void wl_expr_to_instr(wl_Token *tokens, const size_t length) { // const size_t token_size = sizeof(wl_Token); // const size_t length2 = (token_size * length) / token_size; // wl_Token tokens2[length2]; // for (size_t n = 1; n < length2; n++) { // // (n) // if (tokens[n].type == wl_TokenNumber // && tokens[n-1].type == wl_TokenParenOpen // && tokens[MIN(n+1, length)].type == wl_TokenParenClose // ) // tokens2[n-1] = tokens[n]; // else // tokens2[n] = tokens[n]; // } // } void placeholder(wl_Token *tokens) {} typedef struct { const char *string; size_t at; } wl_Source; wl_Source *wl_init_source(const char *string) { if (!string) return NULL; wl_Source *new = ALLOC_STRUCT(wl_Source); if (!new) return NULL; new->string = string; new->at = 0; return new; } bool wl_is_eof(wl_Source *source) { if (!source) return false; return source->at >= strlen(source->string); } char wl_next_char(wl_Source *source) { if (!source) return 0; if (!wl_is_eof(source)) return source->string[source->at++]; else return 0; } /* `inline` attrib throws "undefined reference" errors */ /* inline */ bool is_number(char c) { return 48 <= c && c <= 57; } int main(int argc, char **argv) { const size_t max_tokens = 4096; const char src[] = "2 + 3 * 4"; /* must be = 14 */ bool ok = true; wl_Source *source = wl_init_source(src); if (!source) { printf("wl_Source alloc failed\n"); ok = false; } wl_Token tokens[max_tokens]; if (ok) { // token counter //size_t tok_c = 0; size_t tokpos = 0; char c; while (!wl_is_eof(source)) { if (tokpos >= max_tokens) { printf("reached max tokens count\n"); ok = false; break; } c = wl_next_char(source); if (is_number(c)) { float num = 0; /* `wl_is_eof(source)` will return `true` if we reading last character, so we *first* need to read that character, and *then* advance to next char */ do { if (c == '.') { // TODO: floats } else { num = num * 10 + (c - '0'); } c = wl_next_char(source); } while (!wl_is_eof(source) && is_number(c)); tokens[tokpos++] = (wl_Token){ .type = wl_TokenNumber, .value.num = num }; DBG_PRINTF("new token:%lu: number, %f\n", source->at, num); } else { wl_Token token; switch (c) { case ' ': case '\t': /* skip */ continue; /* skip new token push */ break; case '+': token.type = wl_TokenPlus; break; case '-': token.type = wl_TokenMinus; break; case '*': token.type = wl_TokenMul; break; case '/': token.type = wl_TokenDiv; break; default: printf("%lu: invalid character\n", source->at); ok = false; continue; /* skip new token push */ break; } DBG_PRINTF("new token:%lu: %s\n", source->at, wl_get_token_name(&token)); tokens[tokpos++] = token; } } placeholder(tokens); } free(source); return ok ? 0 : 1; }