Files
armorpaint/base/tools/amake/kong/alang.h
T
2026-03-17 20:24:24 +01:00

344 lines
6.3 KiB
C

// Based on https://github.com/Kode/Kongruent by RobDangerous
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define OPCODES_SIZE (1024 * 1024)
typedef enum variable_kind {
VARIABLE_GLOBAL,
VARIABLE_LOCAL,
VARIABLE_INTERNAL
} variable_kind;
typedef enum access_kind {
ACCESS_MEMBER,
ACCESS_ELEMENT
} access_kind;
typedef enum operatorr {
OPERATOR_EQUALS,
OPERATOR_NOT_EQUALS,
OPERATOR_GREATER,
OPERATOR_GREATER_EQUAL,
OPERATOR_LESS,
OPERATOR_LESS_EQUAL,
OPERATOR_MINUS,
OPERATOR_PLUS,
OPERATOR_DIVIDE,
OPERATOR_MULTIPLY,
OPERATOR_NOT,
OPERATOR_OR,
OPERATOR_BITWISE_XOR,
OPERATOR_BITWISE_AND,
OPERATOR_BITWISE_OR,
OPERATOR_LEFT_SHIFT,
OPERATOR_RIGHT_SHIFT,
OPERATOR_AND,
OPERATOR_MOD,
OPERATOR_ASSIGN,
OPERATOR_MINUS_ASSIGN,
OPERATOR_PLUS_ASSIGN,
OPERATOR_DIVIDE_ASSIGN,
OPERATOR_MULTIPLY_ASSIGN
} operatorr;
typedef uint32_t type_id;
typedef size_t name_id;
typedef struct attribute {
name_id name;
double parameters[16];
uint8_t paramters_count;
} attribute;
typedef struct attributes {
attribute attributes[64];
uint8_t attributes_count;
} attribute_list;
typedef struct unresolved_type_ref {
name_id name;
uint32_t array_size;
} unresolved_type_ref;
typedef struct type_ref {
type_id type;
unresolved_type_ref unresolved;
} type_ref;
typedef struct opcodes {
uint8_t o[OPCODES_SIZE];
size_t size;
} opcodes;
typedef struct function {
attribute_list attributes;
name_id name;
type_ref return_type;
name_id parameter_names[256];
type_ref parameter_types[256];
name_id parameter_attributes[256];
uint8_t parameters_size;
struct statement *block;
opcodes code;
} function;
typedef uint32_t function_id;
typedef struct global_value {
enum {
GLOBAL_VALUE_FLOAT,
GLOBAL_VALUE_INT,
GLOBAL_VALUE_UINT,
GLOBAL_VALUE_BOOL,
GLOBAL_VALUE_NONE
} kind;
union {
float floats[1];
int ints[1];
unsigned uints[1];
bool b;
} value;
} global_value;
typedef struct global {
name_id name;
type_id type;
uint64_t var_index;
global_value value;
attribute_list attributes;
uint32_t usage;
} global;
typedef struct variable {
variable_kind kind;
uint64_t index;
type_ref type;
} variable;
typedef struct access {
access_kind kind;
type_id type;
union {
struct {
name_id name;
} access_member;
struct {
variable index;
} access_element;
};
} access;
typedef struct opcode {
enum {
OPCODE_VAR,
OPCODE_NOT,
OPCODE_NEGATE,
OPCODE_STORE_VARIABLE,
OPCODE_SUB_AND_STORE_VARIABLE,
OPCODE_ADD_AND_STORE_VARIABLE,
OPCODE_DIVIDE_AND_STORE_VARIABLE,
OPCODE_MULTIPLY_AND_STORE_VARIABLE,
OPCODE_STORE_ACCESS_LIST,
OPCODE_SUB_AND_STORE_ACCESS_LIST,
OPCODE_ADD_AND_STORE_ACCESS_LIST,
OPCODE_DIVIDE_AND_STORE_ACCESS_LIST,
OPCODE_MULTIPLY_AND_STORE_ACCESS_LIST,
OPCODE_LOAD_FLOAT_CONSTANT,
OPCODE_LOAD_INT_CONSTANT,
OPCODE_LOAD_BOOL_CONSTANT,
OPCODE_LOAD_ACCESS_LIST,
OPCODE_RETURN,
OPCODE_CALL,
OPCODE_MULTIPLY,
OPCODE_DIVIDE,
OPCODE_MOD,
OPCODE_ADD,
OPCODE_SUB,
OPCODE_EQUALS,
OPCODE_NOT_EQUALS,
OPCODE_GREATER,
OPCODE_GREATER_EQUAL,
OPCODE_LESS,
OPCODE_LESS_EQUAL,
OPCODE_AND,
OPCODE_OR,
OPCODE_BITWISE_XOR,
OPCODE_BITWISE_AND,
OPCODE_BITWISE_OR,
OPCODE_LEFT_SHIFT,
OPCODE_RIGHT_SHIFT,
OPCODE_IF,
OPCODE_WHILE_START,
OPCODE_WHILE_CONDITION,
OPCODE_WHILE_END,
OPCODE_WHILE_BODY,
OPCODE_BLOCK_START,
OPCODE_BLOCK_END
} type;
uint32_t size;
union {
struct {
variable var;
} op_var;
struct {
variable from;
variable to;
} op_negate;
struct {
variable from;
variable to;
} op_not;
struct {
variable from;
variable to;
} op_store_var;
struct {
variable from;
variable to;
access access_list[64];
uint8_t access_list_size;
} op_store_access_list;
struct {
float number;
variable to;
} op_load_float_constant;
struct {
int number;
variable to;
} op_load_int_constant;
struct {
bool boolean;
variable to;
} op_load_bool_constant;
struct {
variable from;
variable to;
access access_list[64];
uint8_t access_list_size;
} op_load_access_list;
struct {
variable var;
} op_return;
struct {
variable var;
name_id func;
variable parameters[64];
uint8_t parameters_size;
} op_call;
struct {
variable right;
variable left;
variable result;
} op_binary;
struct {
variable condition;
uint64_t start_id;
uint64_t end_id;
} op_if;
struct {
uint64_t start_id;
uint64_t continue_id;
uint64_t end_id;
} op_while_start;
struct {
uint64_t start_id;
uint64_t continue_id;
uint64_t end_id;
} op_while_end;
struct {
variable condition;
uint64_t end_id;
} op_while;
struct {
uint64_t id;
} op_block;
struct {
uint8_t nothing;
} op_nothing;
};
} opcode;
typedef struct token {
int line, column;
enum {
TOKEN_NONE,
TOKEN_BOOLEAN,
TOKEN_FLOAT,
TOKEN_INT,
// TOKEN_STRING,
TOKEN_IDENTIFIER,
TOKEN_LEFT_PAREN,
TOKEN_RIGHT_PAREN,
TOKEN_LEFT_CURLY,
TOKEN_RIGHT_CURLY,
TOKEN_LEFT_SQUARE,
TOKEN_RIGHT_SQUARE,
TOKEN_HASH,
TOKEN_IF,
TOKEN_ELSE,
TOKEN_WHILE,
TOKEN_DO,
TOKEN_FOR,
TOKEN_SEMICOLON,
TOKEN_COLON,
TOKEN_DOT,
TOKEN_COMMA,
TOKEN_OPERATOR,
TOKEN_IN,
TOKEN_STRUCT,
TOKEN_FUNCTION,
TOKEN_VAR,
TOKEN_CONST,
TOKEN_RETURN
} kind;
union {
bool boolean;
double number;
// char string[MAX_IDENTIFIER_SIZE];
name_id identifier;
operatorr op;
};
} token;
typedef struct tokens {
token *t;
size_t current_size;
size_t max_size;
} tokens;
typedef struct allocated_global {
global *g;
uint64_t variable_id;
} allocated_global;
function *_get_function(function_id function);
void _names_init(void);
void _types_init(void);
void _functions_init(void);
void _globals_init(void);
void _parse(const char *filename, tokens *tokens);
void _resolve_types(void);
void _compile_function_block(opcodes *code, struct statement *block);
tokens _tokenize(const char *filename, const char *source);
char *_get_name(name_id index);
extern type_id _void_id;
extern type_id _float_id;
extern type_id _int_id;
extern type_id _uint_id;
extern type_id _bool_id;
extern allocated_global __allocated_globals[1024];
extern size_t __allocated_globals_size;