ls

simple syscall based programming language from scratch
git clone git://git.kocotian.pl/ls.git
Log | Files | Refs | README | LICENSE

commit afebae20621401ef1e8ffbbd63dccc2fbaac3fa7
parent 4c8f87ce60081c7a60df9b049b38d9847220210f
Author: kocotian <kocotian@kocotian.pl>
Date:   Wed,  3 Mar 2021 20:02:55 +0100

ASMCONCAT macro, adding and substracting expressions

Diffstat:
Mgrammar.c | 47+++++++++++++++++++++++------------------------
Mutil.c | 10++++++++++
Mutil.h | 1+
3 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/grammar.c b/grammar.c @@ -8,6 +8,11 @@ #include "grammar.h" #include "lsc.h" +#define ASMCONCAT(...) \ + output = realloc(output, outsiz += \ + snprintf(buffer, BUFSIZ, __VA_ARGS__)); \ + strncat(output, buffer, outsiz); + extern char *contents; extern char *output; extern size_t outsiz; @@ -43,24 +48,18 @@ g_expression(Token *tokens, size_t toksize) val = malloc(tokens[i].len + 1); strncpy(val, contents + tokens[i].off, tokens[i].len); val[tokens[i].len] = '\0'; - output = realloc(output, outsiz += - snprintf(buffer, BUFSIZ, "\tmov rax, %s\n", - val)); - strncat(output, buffer, outsiz); + ASMCONCAT("\tmov rax, %s\n", val); free(val); ++i; } else if (tokens[i].type == TokenString) { /* string literal */ val = malloc(tokens[i].len + 1); strncpy(val, contents + tokens[i].off, tokens[i].len); val[tokens[i].len] = '\0'; - output = realloc(output, outsiz += - snprintf(buffer, BUFSIZ, - "section .rodata\n" - "\t.STR%d: db %s, 0\n" - "section .text\n" - "\tmov rax, .STR%d\n", - sciter, val, sciter)); - strncat(output, buffer, outsiz); + ASMCONCAT("section .rodata\n" + "\t.STR%d: db %s, 0\n" + "section .text\n" + "\tmov rax, .STR%d\n", + sciter, val, sciter); free(val); ++i; } else if (tokens[i].type == TokenIdentifier) { /* identifier literal */ @@ -119,27 +118,27 @@ g_expression(Token *tokens, size_t toksize) val = malloc(tokens[i].len + 1); strncpy(val, contents + tokens[i].off, tokens[i].len); val[tokens[i].len] = '\0'; - output = realloc(output, outsiz += - snprintf(buffer, BUFSIZ, "\tmov %s, rax\n", - ai == 0 ? "rdi" : ai == 1 ? "rsi" : - ai == 2 ? "rdx" : ai == 3 ? "r10" : - ai == 4 ? "r8" : ai == 5 ? "r9" : "rax")); - strncat(output, buffer, outsiz); + ASMCONCAT("\tmov %s, rax\n", + ai == 0 ? "rdi" : ai == 1 ? "rsi" : + ai == 2 ? "rdx" : ai == 3 ? "r10" : + ai == 4 ? "r8" : ai == 5 ? "r9" : "rax"); free(val); } while (tokens[i].type == TokenComma); g_expecttype(tokens[i++], TokenClosingParenthesis); - output = realloc(output, outsiz += - snprintf(buffer, BUFSIZ, - "\tmov rax, %d\n\tsyscall\n", - syscallrax)); - strncat(output, buffer, outsiz); + ASMCONCAT("\tmov rax, %d\n\tsyscall\n", syscallrax); } else { if (tokens[i].type == TokenAssignmentSign) { /* expr = expr */ ++i; } else if (tokens[i].type == TokenPlusSign) { /* expr + expr */ + ASMCONCAT("\tpush rax\n"); ++i; + i += g_expression(tokens + i, toksize - i); + ASMCONCAT("\tmov rbx, rax\n\tpop rax\n\tadd rax, rbx\n"); } else if (tokens[i].type == TokenMinusSign) { /* expr - expr */ + ASMCONCAT("\tpush rax\n"); ++i; + i += g_expression(tokens + i, toksize - i); + ASMCONCAT("\tmov rbx, rax\n\tpop rax\n\tsub rax, rbx\n"); } else if (tokens[i].type == TokenPlusEqualSign) { /* expr += expr */ ++i; } else if (tokens[i].type == TokenMinusEqualSign) { /* expr -= expr */ @@ -181,7 +180,7 @@ g_statement(Token *tokens, size_t toksize) i += g_expression(tokens + i, toksize - i); g_expecttype(tokens[i++], TokenClosingParenthesis); i += g_statement(tokens + i, toksize - i); - } else if (!strncmp(contents + tokens[i].off, "while", 5)) { /* loop */ + } else if (!strncmp(contents + tokens[i].off, "while", 5)) { /* while loop */ g_expecttype(tokens[++i], TokenOpeningParenthesis); ++i; i += g_expression(tokens + i, toksize - i); diff --git a/util.c b/util.c @@ -70,6 +70,16 @@ strchlen(const char *s, char c) return p - s; } +ssize_t +strlchlen(const char *s, char c) +{ + char *p; + if ((p = strchr(s, c)) == NULL) + return strlen(s); + while ((p = strchr(p, c) != NULL)) + return p - s; +} + void errwarn(const char *fmt, int iserror, Token token, ...) { diff --git a/util.h b/util.h @@ -11,4 +11,5 @@ void die(const char *fmt, ...); void *ecalloc(size_t nmemb, size_t size); ssize_t nextline(int fd, char *buf, size_t size); ssize_t strchlen(const char *s, char c); +ssize_t strlchlen(const char *s, char c); void errwarn(const char *fmt, int iserror, Token token, ...);