200 lines
4.5 KiB
Plaintext

it should look more like c, as i want my compiler to be able to compile c
#include <io.sterling>//sterling is the name of the language, but i need to think of a file extension name that doesn't conflict with other format
#include <string.h>//this should work
u32 add(u32 a, u32 b) {
return (a + b);
}
// also i should be able as the user to define
typedef struct {
u32 test = 12;
} new_struct;
// if new_struct struct = {0}; then all data even default init are set to 0
// but if new_struct struct = {}; then all data but default init are set to 0
//also pointer should work like c, but void* shouldn't be the same as ptr*
//i don't know what i could do, but i would like for ptr* to allow for implicite data cast, but void* should be explicit
meta define_add(T);
T add(T a, T b) {
return (a + b);
}
//the issue i have here is it need to have an explicit overload if T is a structure, and i don't really like it, could lead to a c++ like language with too many undefined behavior, what could be a better approach ?
#include <io.stgh>//for stg header but i could also just use .stg and have the possibility to include stg file as header
#include <string.h>
typedef struct {
u32 x = 1;
u32 y = 2;
} vec2;
typedef struct {
u32 x;
u32 y;
} vec2_raw;
u32 add(u32 a, u32 b) {
return (a + b);
}
vec2_raw make_raw(u32 a, u32 b) {
return (vec2_raw){ a, b };
}
void* memcpy_explicit(void* dst, void* src, u32 n) {
// must explicitly cast outside
return memcpy(dst, src, n);
}
fn copy(ptr* dst, ptr* src, u32 n) {
// compiler auto-casts any ptr* to void* internally
memcpy(dst, src, n);
}
meta define_add(T);
T add(T a, T b) {
return (a + b);
}
// specialization for vec2
meta define_add(vec2);
vec2 add(vec2 a, vec2 b) {
return (vec2){ a.x + b.x, a.y + b.y };
}
fn main() -> u32 {
vec2 a = {}; // defaults apply
vec2 b = {0}; // defaults ignored, all zero
vec2 result = add(a, b);
u32* data = 0;
copy(data, data, 4); // OK
memcpy_explicit((void*)data, (void*)data, 4); // must cast
return 0;
}
fn_asm exit() {
section .text
global exit
exit:
mov rax, 60 ; syscall for exit
mov rdi, 0 ; exit code
syscall
ret
}
/*
rdi: dst
rsi: value
rdx: size
Returns in rax: dst
*/
/* implicit
section .text
global <symbol>
memset:
*/
fn_asm memset(void* dst, u8 value, u64 size) {
test rdx, rdx
je .done
mov rax, rsi ; value
mov rdi, rdi ; dst
mov rcx, rdx ; size
rep stosb
.done:
mov rax, rdi ; return dst
ret
}
//This uses the rep stosb instruction to rapidly write bytes into memory.
/*
rdi: void** old_sp — destination to store current rsp
rsi: void* new_sp — new stack pointer to switch into
No return value (control flow continues on new stack)
*/
fn_asm context_switch(void** old_sp, void* new_sp) {
mov [rdi], rsp ; save current stack pointer to *old_sp
mov rsp, rsi ; load new stack pointer
ret
}
/*
rdi: dst
rsi: value
rdx: size
Returns in rax: dst
*/
/* implicit
section .text
memset:
*/
fn_static_asm memset(void* dst, u8 value, u64 size) {
test rdx, rdx
je .done
mov rax, rsi ; value
mov rdi, rdi ; dst
mov rcx, rdx ; size
rep stosb
.done:
mov rax, rdi ; return dst
ret
}
//This uses the rep stosb instruction to rapidly write bytes into memory.
/*
| Keyword | Description |
| --------------- | ---------------------------------------------------------------------- |
| `fn` | Required for every function definition |
| `fn_inline` | Inline-only function, callable in the same TU |
| `fn_static` | Internal linkage (only visible in current TU) |
| `fn_extern` | Declaration only; expects symbol at link time |
| `fn_export` | Visible outside, exported in shared/static libs |
| `fn_asm` | Assembly-defined function, globally visible unless otherwise specified |
| `fn_static_asm` | Assembly-defined, internal linkage (hidden from linker) |
*/
//Keyword Examples
// header file (user_math.stgh)
fn_extern add(u32, u32);
fn_inline max(u32 a, u32 b) {
return (a > b) ? a : b;
}
// libmath.stg
fn_export add(u32 a, u32 b) {
return a + b;
}
// internal use only
fn_static log2_floor(u32 x) {
// implementation
}
// inline asm
fn_asm fast_add(u32 a, u32 b) {
mov eax, edi
add eax, esi
ret
}
// internal-only asm
fn_static_asm zero_block(void* dst, u64 size) {
rep stosb
ret
}