aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-06-18 15:17:14 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-06-18 15:17:14 +0200
commite8dcd5bbc2c92dd82c6f7c405ab4f95956b35dec (patch)
tree969fece9de69b101dd3534997a9959401d69cc2f /src
parentc35e4faf918e8076012c881519687b7bbccaf5eb (diff)
Add 128-bit integers
Diffstat (limited to 'src')
-rw-r--r--src/codegen.c33
-rw-r--r--src/primitives.gperf2
2 files changed, 20 insertions, 15 deletions
diff --git a/src/codegen.c b/src/codegen.c
index 4e2a4d3..f8a3f32 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -12,11 +12,11 @@
#include "parser.h"
#include "types.h"
-static size_t codegenstmt(LLVMBuilderRef, LLVMValueRef *, struct ast,
- struct lexemes, size_t)
+static size_t codegenstmt(LLVMBuilderRef, LLVMValueRef *, struct type *,
+ struct ast, struct lexemes, size_t)
__attribute__((nonnull));
-static size_t codegenexpr(LLVMBuilderRef, LLVMValueRef *, struct ast,
- struct lexemes, size_t, LLVMValueRef *)
+static size_t codegenexpr(LLVMBuilderRef, LLVMValueRef *, struct type *,
+ struct ast, struct lexemes, size_t, LLVMValueRef *)
__attribute__((nonnull));
static LLVMTypeRef type2llvm(struct type);
@@ -43,7 +43,7 @@ codegen(const char *file, struct type *types, struct ast ast,
LLVMTypeRef T = type2llvm(types[i]);
LLVMValueRef globl, val;
globl = LLVMAddGlobal(mod, T, name);
- i = codegenexpr(builder, declvals, ast, toks, ast.kids[i].rhs, &val);
+ i = codegenexpr(builder, declvals, types, ast, toks, ast.kids[i].rhs, &val);
LLVMSetInitializer(globl, LLVMConstTrunc(val, T));
free(name);
break;
@@ -86,7 +86,7 @@ codegen(const char *file, struct type *types, struct ast ast,
free(fnname);
for (i = ast.kids[body].lhs; i <= ast.kids[body].rhs;)
- i = codegenstmt(builder, declvals, ast, toks, i);
+ i = codegenstmt(builder, declvals, types, ast, toks, i);
break;
}
default:
@@ -106,8 +106,8 @@ codegen(const char *file, struct type *types, struct ast ast,
}
size_t
-codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast,
- struct lexemes toks, size_t i)
+codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct type *types,
+ struct ast ast, struct lexemes toks, size_t i)
{
switch (ast.kinds[i]) {
case ASTRET:
@@ -116,7 +116,8 @@ codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast,
return i + 1;
}
LLVMValueRef v;
- i = codegenexpr(builder, declvals, ast, toks, ast.kids[i].rhs, &v);
+ i = codegenexpr(builder, declvals, types, ast, toks, ast.kids[i].rhs,
+ &v);
LLVMBuildRet(builder, v);
return i;
}
@@ -126,9 +127,10 @@ codegenstmt(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast,
}
size_t
-codegenexpr(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast,
- struct lexemes toks, size_t i, LLVMValueRef *v)
+codegenexpr(LLVMBuilderRef builder, LLVMValueRef *declvals, struct type *types,
+ struct ast ast, struct lexemes toks, size_t i, LLVMValueRef *v)
{
+ (void)declvals;
(void)builder;
switch (ast.kinds[i]) {
case ASTNUMLIT: {
@@ -146,10 +148,11 @@ codegenexpr(LLVMBuilderRef builder, LLVMValueRef *declvals, struct ast ast,
p[len++] = sv.p[i];
}
- *v = LLVMConstIntOfStringAndSize(LLVMInt64Type(), p, len, 10);
+ *v = LLVMConstIntOfStringAndSize(type2llvm(types[i]), p, len, 10);
free(p);
} else
- *v = LLVMConstIntOfStringAndSize(LLVMInt64Type(), sv.p, sv.len, 10);
+ *v = LLVMConstIntOfStringAndSize(type2llvm(types[i]), sv.p, sv.len,
+ 10);
return i + 1;
}
case ASTIDENT:
@@ -177,8 +180,8 @@ type2llvm(struct type t)
assert(t.issigned);
/* TODO: Arbitrary precision */
if (t.size == 0)
- t.size = 8;
- return LLVMIntType(t.size * 8);
+ return LLVMInt128Type();
+ return LLVMIntType((unsigned)t.size * 8);
default:
__builtin_unreachable();
}
diff --git a/src/primitives.gperf b/src/primitives.gperf
index 7594b29..ea7543b 100644
--- a/src/primitives.gperf
+++ b/src/primitives.gperf
@@ -20,11 +20,13 @@ i8, { TYPE_NUM, 1, true }
i16, { TYPE_NUM, 2, true }
i32, { TYPE_NUM, 4, true }
i64, { TYPE_NUM, 8, true }
+i128, { TYPE_NUM, 16, true }
int, { TYPE_NUM, 8, true }
u8, { TYPE_NUM, 1, false }
u16, { TYPE_NUM, 2, false }
u32, { TYPE_NUM, 4, false }
u64, { TYPE_NUM, 8, false }
+u128, { TYPE_NUM, 16, false }
uint, { TYPE_NUM, 8, false }
rune, { TYPE_RUNE, 4, true }
%%