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:
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, ...);