calc

Simple math expression parser.
git clone git://git.amin.space/calc.git
Log | Files | Refs | LICENSE

commit 89878fdbc63a7c562b91847e8020578822f9adbf
parent 7fe98576acd7ec303e7e88110942fa622e0d1aca
Author: amin <dev@aminmesbah.com>
Date:   Sat, 27 Oct 2018 05:23:21 +0000

Be parseful

FossilOrigin-Name: b95ce4ca2461de1db0a5575310fef8d2655224103828fd583ad14cd9226286e8
Diffstat:
Mcalc.c | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 144 insertions(+), 0 deletions(-)

diff --git a/calc.c b/calc.c @@ -1,9 +1,12 @@ #include <assert.h> +#include <ctype.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#define global_variable static + struct BufHdr { size_t cap; size_t len; @@ -75,7 +78,148 @@ void buf_test(void) printf("\n"); } +enum TokenKind { + // first 128 values reserved to match up with ascii + TOKEN_INT = 128, + TOKEN_NAME, +}; + +struct Token { + enum TokenKind kind; + union { + uint64_t val; + struct { + const char *start; + const char *end; + }; + }; +}; + +global_variable struct Token g_token; +global_variable const char *g_stream; + +void lex_next_token() { + switch(*g_stream) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + uint64_t val = 0; + while (isdigit(*g_stream)) + { + val *= 10; + val += *g_stream++ - '0'; + } + g_token.kind = TOKEN_INT; + g_token.val = val; + break; + } + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '_': { + const char *start = g_stream++; + while (isalnum(*g_stream) || *g_stream == '_') + { + g_stream++; + } + g_token.kind = TOKEN_NAME; + g_token.start = start; + g_token.end = g_stream; + break; + } + default: + g_token.kind = *g_stream++; + break; + } +} + +void print_token(struct Token token) +{ + switch(token.kind) + { + case TOKEN_INT: + printf("TOKEN_INT: %lu\n", token.val); + break; + case TOKEN_NAME: + printf("TOKEN_NAME: %.*s\n", (int)(token.end - token.start), token.start); + break; + default: + printf("TOKEN: '%c'\n", token.kind); + break; + } +} + +void lex_test() +{ + char *source = "+()_HELLO1,234+FOO!994"; + g_stream = source; + lex_next_token(); + while (g_token.kind) + { + print_token(g_token); + lex_next_token(); + } +} + int main(void) { buf_test(); + lex_test(); }