I forgor

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2024-04-10 11:34:43 +03:00
parent d069f037a7
commit 1caebf3295
10 changed files with 264 additions and 39 deletions

View File

@ -5,5 +5,5 @@ set -xe
LLVMC=llvm-config
LLVM_LINKER="-lc++ $($LLVMC --libs core --cxxflags --ldflags --system-libs|tr '\n' ' ')"
odin run src -o:none -debug -out:speedcat -extra-linker-flags:"$LLVM_LINKER" -- test_type_checker.cat
clang -I/opt/local/include -L/opt/local/lib -lraylib -lm -framework Cocoa -framework OpenGL -framework IOKit test_type_checker.ll test.c -o raylib
odin run src -o:none -debug -out:speedcat -extra-linker-flags:"$LLVM_LINKER" -- pong.cat
clang -I/opt/local/include -L/opt/local/lib -lraylib -lm -framework Cocoa -framework OpenGL -framework IOKit pong.ll -o raylib

145
pong.cat Normal file
View File

@ -0,0 +1,145 @@
struct Color {
r g b a: u8,
}
fn InitWindow(w h: i32, title: []u8)
fn CloseWindow
fn BeginDrawing
fn SetTargetFPS(fps: i32)
fn EndDrawing
fn DrawFPS(x y: i32)
fn WindowShouldClose i32
struct Rectangle {
x y w h: f32,
}
fn ColorToRaylib(c: Color) u32 {
ret c.a as u32 << 24 as u32 | c.b as u32 << 16 as u32 | c.g as u32 << 8 as u32 | c.r
}
fn ClearBackgroundWrap(c: Color) {
fn ClearBackground(c: u32)
ClearBackground (ColorToRaylib c)
}
fn DrawRectangleWrap(x y w h: i32, c: Color) {
fn DrawRectangle(x y w h: i32, c: u32)
DrawRectangle x y w h (ColorToRaylib c)
}
fn DrawCircleWrap(x y: i32, r: f32, c: Color) {
fn DrawCircle(x y: i32, r: f32, c: u32)
DrawCircle x y r (ColorToRaylib c)
}
fn DrawRectangleRecWrap(r: Rectangle, c: Color) {
fn DrawRectangleRec(r: Rectangle, c: u32)
DrawRectangleRec r (ColorToRaylib c)
}
fn DrawTextWrap(text: []u8, x y size: i32, c: Color) {
fn DrawText(text: []u8, x y size: i32, c: u32)
DrawText text x y size (ColorToRaylib c)
}
let WHITE :: .Color{255 255 255 255}
let BLACK :: .Color{0 0 0 255}
let RED :: .Color{255 0 0 255}
let BLUE :: .Color{0 0 255 255}
InitWindow 800 450 "poop"
SetTargetFPS 60
fn GetScreenWidth i32
fn GetScreenHeight i32
let logox := GetScreenWidth / 2 - 128
let logoy := GetScreenHeight / 2 - 128
\ FIXME: Cannot inline
let fc := 0
let lc := 0
let top_side_rec_width := 16
let left_side_rec_height := 16
let bottom_side_rec_width := 16
let right_side_rec_height := 16
let state := 0
let alpha := 1.0
for WindowShouldClose == 0 {
if state == 0 {
fc = fc + 1
if fc == 120 {
state = 1
fc = 0
}
} elif state == 1 {
top_side_rec_width = top_side_rec_width + 4
left_side_rec_height = left_side_rec_height + 4
if top_side_rec_width == 256 {
state = 2
}
} elif state == 2 {
bottom_side_rec_width = bottom_side_rec_width + 4
right_side_rec_height = right_side_rec_height + 4
if bottom_side_rec_width == 256 {
state = 3
}
} elif state == 3 {
fc = fc + 1
if fc / 12 != 0 {
lc = lc + 1
fc = 0
}
if lc >= 10 {
alpha = alpha - 0.02
if alpha <= 0.0 {
alpha = 0.0
state = 4
}
}
}
BeginDrawing
ClearBackgroundWrap WHITE
if state == 0 {
DrawFPS 20 20
if (fc/15)%2 != 0 {
DrawRectangleWrap logox logoy 16 16 BLACK
}
} elif state == 1 {
DrawRectangleWrap logox logoy top_side_rec_width 16 BLACK
DrawRectangleWrap logox logoy 16 left_side_rec_height BLACK
} elif state == 2 {
DrawRectangleWrap logox logoy top_side_rec_width 16 BLACK
DrawRectangleWrap logox logoy 16 left_side_rec_height BLACK
DrawRectangleWrap logox+240 logoy 16 right_side_rec_height BLACK
DrawRectangleWrap logox logoy+240 bottom_side_rec_width 16 BLACK
} elif state == 3 {
let colorw := .Color{255 255 255 (alpha*255.0) as u8}
let colorb := .Color{0 0 0 (alpha*255.0) as u8}
\ FIXME: ADD field access assignment
\color.a = (alpha * 255.0) as u8
DrawRectangleWrap logox logoy top_side_rec_width 16 colorb
DrawRectangleWrap logox logoy+16 16 left_side_rec_height-32 colorb
DrawRectangleWrap logox+240 logoy+16 16 right_side_rec_height-32 cbolor
DrawRectangleWrap logox logoy+240 bottom_side_rec_width 16 colorb
DrawRectangleWrap GetScreenWidth/2-112 GetScreenHeight/2-112 224 224 colorw
\ DrawText(TextSubtext("raylib", 0, lettersCount), GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
\ DrawTextWrap "raylib" GetScreenWidth/2-44 GetScreenHeight/2+48 50 BLACK
}
EndDrawing
}
CloseWindow
"asf"

View File

@ -42,7 +42,8 @@ source_print :: proc(data: ^[]u8, range: TextRange) {
} else {
fmt.printf("%c", ch)
}
if pos == range.end {
a := TextPosition{range.end.line, range.end.column - 1}
if pos == a {
fmt.printf("\x1B[0m")
}
}

View File

@ -279,6 +279,7 @@ lexer_read_string :: proc(lexer: ^Lexer, kind: TokenKind, outer: u8) -> Token {
lexer_advance(lexer)
}
crange.range.end = lexer.position
append(&str, 0)
return token_create_u8(kind, str, crange)
}

View File

@ -11,6 +11,7 @@ LLVMScope :: struct {
}
g_llvm_scope_stack := [dynamic]LLVMScope{}
g_last_alloca: LLVMValueRef
llvm_scope_find_definition :: proc(name: ^[dynamic]u8) -> LLVMValueRef {
#reverse for &scope in g_llvm_scope_stack {
@ -66,6 +67,25 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
return fmt.caprintf("scope_%d", scope_num)
}
generate_llvm_string :: proc(
ctx: LLVMContextRef,
mod: LLVMModuleRef,
builder: LLVMBuilderRef,
node: ^Node,
) -> LLVMValueRef {
value := node.value.([dynamic]u8)
str_type := LLVMArrayType(LLVMInt8Type(), u64(len(value)))
str := LLVMAddGlobal(mod, str_type, "str")
LLVMSetInitializer(str, LLVMConstString(cstring(raw_data(value[:])), len(value), 1))
LLVMSetGlobalConstant(str, 1)
LLVMSetLinkage(str, .PrivateLinkage)
LLVMSetUnnamedAddress(str, .GlobalUnnamedAddr)
LLVMSetAlignment(str, 1)
zi := LLVMConstInt(LLVMInt64Type(), 0, 1)
indexes := [2]LLVMValueRef{zi, zi}
return LLVMBuildInBoundsGEP2(builder, str_type, str, raw_data(indexes[:]), 2, "")
}
generate_llvm_integer :: proc(
ctx: LLVMContextRef,
mod: LLVMModuleRef,
@ -304,6 +324,8 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
) -> LLVMValueRef {
if node.kind == .Integer {
return generate_llvm_integer(ctx, mod, builder, node)
} else if node.kind == .String {
return generate_llvm_string(ctx, mod, builder, node)
} else if node.kind == .Float {
return generate_llvm_float(ctx, mod, builder, node)
} else if node.kind == .FunctionCall {
@ -324,12 +346,17 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
return nil
}
struct_value := g_last_alloca
//struct_value := LLVMBuildAlloca(builder, struct_type, "structini")
//struct_value := LLVMConstNamedStruct(struct_type, raw_data(struct_values[:]), len(struct_values))
struct_values := [dynamic]LLVMValueRef{}
for &field, i in node.children[:] {
field_value := generate_llvm_expression(ctx, mod, builder, field)
ptr_field := LLVMBuildStructGEP2(builder, struct_type, struct_value, uint(i), "inigep")
LLVMBuildStore(builder, field_value, ptr_field)
append(&struct_values, field_value)
}
struct_value := LLVMConstNamedStruct(struct_type, raw_data(struct_values[:]), len(struct_values))
return struct_value
} else if node.kind == .FieldAccess {
if node.children[0].kind == .FieldAccess {
@ -360,6 +387,22 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
fmt.panicf("FIXME: Implement other node kinds. Got: {}", node.kind)
}
generate_llvm_bit_cast :: proc(
ctx: LLVMContextRef,
mod: LLVMModuleRef,
builder: LLVMBuilderRef,
node: ^Node,
) -> LLVMValueRef {
value := generate_llvm_expression(ctx, mod, builder, node.children[0])
if value == nil {
return nil
}
type := generate_llvm_type_from_node(ctx, mod, builder, node.return_type)
casted := LLVMBuildBitCast(builder, value, type, "tmpbitcast")
return casted
}
generate_llvm_cast :: proc(
ctx: LLVMContextRef,
mod: LLVMModuleRef,
@ -372,10 +415,20 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
}
if node.return_type.kind == .Integer {
if node.children[0].return_type.kind == .Float {
if node.return_type.bit_size == 32 {
return LLVMBuildFPToSI(builder, value, LLVMInt32TypeInContext(ctx), "casttmp")
} else if node.return_type.bit_size == 64 {
return LLVMBuildFPToSI(builder, value, LLVMInt64TypeInContext(ctx), "casttmp")
if node.return_type.is_signed {
return LLVMBuildFPToSI(
builder,
value,
LLVMIntTypeInContext(ctx, uint(node.return_type.bit_size)),
"casttmpsi",
)
} else {
return LLVMBuildFPToUI(
builder,
value,
LLVMIntTypeInContext(ctx, uint(node.return_type.bit_size)),
"casttmpui",
)
}
} else if node.children[0].return_type.kind == .Integer {
if node.return_type.is_signed && node.children[0].return_type.is_signed {
@ -442,8 +495,12 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
if node.kind == .Cast {
return generate_llvm_cast(ctx, mod, builder, node)
}
if node.kind == .BitwiseCast {
return generate_llvm_bit_cast(ctx, mod, builder, node)
}
if node.kind == .Integer ||
node.kind == .Float ||
node.kind == .String ||
node.kind == .FunctionCall ||
node.kind == .Identifier ||
node.kind == .StructInitializer ||
@ -812,6 +869,8 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
fallthrough
case .UnaryExpression:
fallthrough
case .String:
fallthrough
case .BinaryExpression:
generate_llvm_expression(ctx, mod, builder, node)
case .VariableDeclaration:
@ -821,9 +880,13 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
type,
strings.clone_to_cstring(string(node.children[0].value.([dynamic]u8)[:])),
)
g_last_alloca = var
if node.children[2] != nil {
value := generate_llvm_expression(ctx, mod, builder, node.children[2])
LLVMBuildStore(builder, value, var)
// FIXME: Add support for pointers
if LLVMGetTypeKind(LLVMTypeOf(value)) != .LLVMPointerTypeKind {
LLVMBuildStore(builder, value, var)
}
}
llvm_top_scope().definitions[get_character_sum_of_dyn_arr(&node.children[0].value.([dynamic]u8))] = var
llvm_top_scope().types[get_character_sum_of_dyn_arr(&node.children[0].value.([dynamic]u8))] = type

View File

@ -26,6 +26,12 @@ LLVMComdatRef :: distinct rawptr
LLVMJITEventListenerRef :: distinct rawptr
LLVMBinaryRef :: distinct rawptr
LLVMnnamedAddr :: enum {
NoUnnamedAddr,
LocalUnnamedAddr,
GlobalUnnamedAddr,
}
LLVMTypeKind :: enum {
LLVMVoidTypeKind,
LLVMHalfTypeKind,
@ -50,6 +56,26 @@ LLVMTypeKind :: enum {
LLVMTargetExtTypeKind,
}
LLVMLinkage :: enum {
ExternalLinkage,
AvailableExternallyLinkage,
LinkOnceAnyLinkage,
LinkOnceODRLinkage,
LinkOnceODRAutoHideLinkage,
WeakAnyLinkage,
WeakODRLinkage,
AppendingLinkage,
InternalLinkage,
PrivateLinkage,
DLLImportLinkage,
DLLExportLinkage,
ExternalWeakLinkage,
GhostLinkage,
CommonLinkage,
LinkerPrivateLinkage,
LinkerPrivateWeakLinkage,
}
LLVMIntPredicate :: enum {
LLVMIntEQ = 32,
LLVMIntNE,
@ -100,6 +126,11 @@ foreign llvmc {
LLVMBuildRetVoid :: proc(Builder: LLVMBuilderRef) -> LLVMValueRef ---
LLVMBuildRet :: proc(Builder: LLVMBuilderRef, V: LLVMValueRef) -> LLVMValueRef ---
LLVMConstString :: proc(Str: cstring, Length: uint, DontNullTerminate: LLVMBool) -> LLVMValueRef ---
LLVMInt8Type :: proc() -> LLVMTypeRef ---
LLVMArrayType :: proc(ElementType: LLVMTypeRef, ElementCount: u64) -> LLVMTypeRef ---
LLVMInt64Type :: proc() -> LLVMTypeRef ---
LLVMInt1TypeInContext :: proc(C: LLVMContextRef) -> LLVMTypeRef ---
LLVMInt8TypeInContext :: proc(C: LLVMContextRef) -> LLVMTypeRef ---
LLVMInt16TypeInContext :: proc(C: LLVMContextRef) -> LLVMTypeRef ---
@ -175,12 +206,14 @@ foreign llvmc {
LLVMBuildPhi :: proc(Builder: LLVMBuilderRef, Ty: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildFPToSI :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildFPToUI :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildSExt :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildZExt :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildIntCast :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildSIToFP :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildFPTrunc :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildFPExt :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildBitCast :: proc(Builder: LLVMBuilderRef, Val: LLVMValueRef, DestTy: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMBuildStructGEP2 :: proc(Builder: LLVMBuilderRef, Ty: LLVMTypeRef, Pointer: LLVMValueRef, Idx: uint, Name: cstring) -> LLVMValueRef ---
@ -196,4 +229,12 @@ foreign llvmc {
LLVMSetValueName2 :: proc(Val: LLVMValueRef, Name: cstring, Length: u64) ---
LLVMGetReturnType :: proc(Fn: LLVMTypeRef) -> LLVMTypeRef ---
LLVMAddGlobal :: proc(M: LLVMModuleRef, Ty: LLVMTypeRef, Name: cstring) -> LLVMValueRef ---
LLVMSetInitializer :: proc(GlobalVar: LLVMValueRef, ConstantVal: LLVMValueRef) ---
LLVMSetGlobalConstant :: proc(GlobalVar: LLVMValueRef, Val: LLVMBool) ---
LLVMSetLinkage :: proc(GlobalVar: LLVMValueRef, Linkage: LLVMLinkage) ---
LLVMSetUnnamedAddress :: proc(GlobalVar: LLVMValueRef, UnnamedAddress: LLVMnnamedAddr) ---
LLVMSetAlignment :: proc(GlobalVar: LLVMValueRef, Bytes: uint) ---
LLVMBuildInBoundsGEP2 :: proc(Builder: LLVMBuilderRef, Ty: LLVMTypeRef, Pointer: LLVMValueRef, Indices: [^]LLVMValueRef, NumIndices: uint, Name: cstring) -> LLVMValueRef ---
}

View File

@ -44,7 +44,7 @@ main :: proc() {
//fmt.printf("%s\n", msg)
}
if contains_errors {
return
os.exit(1)
}
}
//node_print(ast)
@ -61,7 +61,7 @@ main :: proc() {
//fmt.printf("%s\n", msg)
}
if contains_errors {
return
os.exit(1)
}
}

View File

@ -56,7 +56,7 @@ FunctionType :: struct {
compare_types :: proc(a: ^Type, b: ^Type) -> (ret: bool, cast_required: bool) {
cast_required = false
if (a == nil && b != nil) || (a != nil && b == nil) {
if (a == nil && b != nil) || (a != nil && b == nil) || (a == nil && b == nil) {
ret = false
return
}

View File

@ -61,7 +61,7 @@ infer_type :: proc(parent: ^Node, child: ^Node) {
case .Float:
child.return_type = type_create_float(32)
case .String:
child.return_type = type_create_array(type_create_integer(32, false), 0)
child.return_type = type_create_array(type_create_integer(8, false), 0)
case .Character:
child.return_type = type_create_integer(32, false)
}

26
test.c
View File

@ -1,26 +0,0 @@
#include <stdint.h>
// void ClearBackground(uint64_t rgba);
// void ClearBackgroundWrap(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
// ClearBackground((uint64_t)r << 24 | (uint64_t)g << 16 | (uint64_t)b << 8 |
// (uint64_t)a);
// }
//
// void DrawRectangle(uint32_t x, uint32_t y, uint32_t width, uint32_t height,
// uint64_t rgba);
// void DrawRectangleWrap(uint32_t x, uint32_t y, uint32_t width, uint32_t
// height,
// uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
// DrawRectangle(x, y, width, height,
// (uint64_t)r << 24 | (uint64_t)g << 16 | (uint64_t)b << 8 |
// (uint64_t)a);
// }
//
// void DrawCircle(uint32_t x, uint32_t y, float radius, uint64_t rgba);
// void DrawCircleWrap(uint32_t x, uint32_t y, float radius, uint8_t r, uint8_t
// g,
// uint8_t b, uint8_t a) {
// DrawCircle(x, y, radius,
// (uint64_t)r << 24 | (uint64_t)g << 16 | (uint64_t)b << 8 |
// (uint64_t)a);
// }