cstr -> str where possible
This commit is contained in:
parent
8a38813ba5
commit
823223ffa7
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
|
#include "../string/str.h"
|
||||||
|
|
||||||
typedef union Register {
|
typedef union Register {
|
||||||
u32 u32v;
|
u32 u32v;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "List.h"
|
#include "List.h"
|
||||||
|
|
||||||
List_define(cstr);
|
|
||||||
List_define(u32);
|
List_define(u32);
|
||||||
List_define(u8);
|
List_define(u8);
|
||||||
|
|||||||
@ -54,6 +54,5 @@
|
|||||||
}\
|
}\
|
||||||
|
|
||||||
|
|
||||||
List_declare(cstr);
|
|
||||||
List_declare(u32);
|
List_declare(u32);
|
||||||
List_declare(u8);
|
List_declare(u8);
|
||||||
|
|||||||
@ -5,30 +5,30 @@ List_define(Operation);
|
|||||||
List_define(DataDefinition);
|
List_define(DataDefinition);
|
||||||
List_define(Section);
|
List_define(Section);
|
||||||
|
|
||||||
static cstr _ArgumentType_str[] = {
|
static str _ArgumentType_str[] = {
|
||||||
"Unset",
|
STR("Unset"),
|
||||||
"Register",
|
STR("Register"),
|
||||||
"ConstValue",
|
STR("ConstValue"),
|
||||||
"DataName",
|
STR("DataName"),
|
||||||
"NamedDataPointer",
|
STR("NamedDataPointer"),
|
||||||
"NamedDataSize",
|
STR("NamedDataSize"),
|
||||||
};
|
};
|
||||||
|
|
||||||
cstr ArgumentType_toString(ArgumentType t){
|
str ArgumentType_toString(ArgumentType t){
|
||||||
if(t >= ARRAY_SIZE(_ArgumentType_str))
|
if(t >= ARRAY_SIZE(_ArgumentType_str))
|
||||||
return "!!INDEX_ERROR!!";
|
return STR("!!INDEX_ERROR!!");
|
||||||
return _ArgumentType_str[t];
|
return _ArgumentType_str[t];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Section_init(Section* sec, char* name){
|
void Section_init(Section* sec, str name){
|
||||||
sec->name = name;
|
sec->name = name;
|
||||||
sec->data = List_DataDefinition_alloc(256);
|
sec->data = List_DataDefinition_alloc(256);
|
||||||
sec->code = List_Operation_alloc(1024);
|
sec->code = List_Operation_alloc(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Section_free(Section* sec){
|
void Section_free(Section* sec){
|
||||||
free(sec->name);
|
free(sec->name.data);
|
||||||
free(sec->data.data);
|
free(sec->data.data);
|
||||||
free(sec->code.data);
|
free(sec->code.data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
|
#include "../string/str.h"
|
||||||
#include "../instructions/instructions.h"
|
#include "../instructions/instructions.h"
|
||||||
#include "../collections/List.h"
|
#include "../collections/List.h"
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ typedef enum ArgumentType {
|
|||||||
ArgumentType_NamedDataSize,
|
ArgumentType_NamedDataSize,
|
||||||
} ArgumentType;
|
} ArgumentType;
|
||||||
|
|
||||||
cstr ArgumentType_toString(ArgumentType t);
|
str ArgumentType_toString(ArgumentType t);
|
||||||
|
|
||||||
|
|
||||||
typedef struct Argument {
|
typedef struct Argument {
|
||||||
@ -32,7 +33,7 @@ List_declare(Operation);
|
|||||||
|
|
||||||
|
|
||||||
typedef struct DataDefinition {
|
typedef struct DataDefinition {
|
||||||
cstr name;
|
str name;
|
||||||
List_u8 data;
|
List_u8 data;
|
||||||
u32 element_size;
|
u32 element_size;
|
||||||
} DataDefinition;
|
} DataDefinition;
|
||||||
@ -41,14 +42,14 @@ List_declare(DataDefinition);
|
|||||||
|
|
||||||
|
|
||||||
typedef struct Section {
|
typedef struct Section {
|
||||||
char* name;
|
str name;
|
||||||
List_DataDefinition data;
|
List_DataDefinition data;
|
||||||
List_Operation code;
|
List_Operation code;
|
||||||
} Section;
|
} Section;
|
||||||
|
|
||||||
List_declare(Section);
|
List_declare(Section);
|
||||||
|
|
||||||
void Section_init(Section* Section, char* name);
|
void Section_init(Section* Section, str name);
|
||||||
void Section_free(Section* Section);
|
void Section_free(Section* Section);
|
||||||
|
|
||||||
typedef struct AST {
|
typedef struct AST {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "Compiler_internal.h"
|
#include "Compiler_internal.h"
|
||||||
|
|
||||||
|
|
||||||
void Compiler_init(Compiler* cmp){
|
void Compiler_init(Compiler* cmp){
|
||||||
memset(cmp, 0, sizeof(Compiler));
|
memset(cmp, 0, sizeof(Compiler));
|
||||||
cmp->state = CompilerState_Initial;
|
cmp->state = CompilerState_Initial;
|
||||||
@ -10,7 +9,7 @@ void Compiler_init(Compiler* cmp){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Compiler_free(Compiler* cmp){
|
void Compiler_free(Compiler* cmp){
|
||||||
free(cmp->code);
|
free(cmp->code.data);
|
||||||
free(cmp->tokens.data);
|
free(cmp->tokens.data);
|
||||||
free(cmp->line_lengths.data);
|
free(cmp->line_lengths.data);
|
||||||
AST_free(&cmp->ast);
|
AST_free(&cmp->ast);
|
||||||
@ -18,7 +17,7 @@ void Compiler_free(Compiler* cmp){
|
|||||||
|
|
||||||
CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos){
|
CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos){
|
||||||
u32 prev_lines_len = 0;
|
u32 prev_lines_len = 0;
|
||||||
if(pos >= cmp->code_len)
|
if(pos >= cmp->code.len)
|
||||||
return CodePos_create(0, 0);
|
return CodePos_create(0, 0);
|
||||||
|
|
||||||
for(u32 i = 0; i < cmp->line_lengths.len; i++){
|
for(u32 i = 0; i < cmp->line_lengths.len; i++){
|
||||||
@ -33,8 +32,8 @@ CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos){
|
|||||||
|
|
||||||
void _Compiler_setError(Compiler* cmp, cstr context, cstr format, ...){
|
void _Compiler_setError(Compiler* cmp, cstr context, cstr format, ...){
|
||||||
// happens at the end of file
|
// happens at the end of file
|
||||||
if(cmp->pos >= cmp->code_len)
|
if(cmp->pos >= cmp->code.len)
|
||||||
cmp->pos = cmp->code_len - 1;
|
cmp->pos = cmp->code.len - 1;
|
||||||
char position_str[32];
|
char position_str[32];
|
||||||
CodePos code_pos = Compiler_getLineAndColumn(cmp, cmp->pos);
|
CodePos code_pos = Compiler_getLineAndColumn(cmp, cmp->pos);
|
||||||
sprintf(position_str, "[at %u:%u][", code_pos.line, code_pos.column);
|
sprintf(position_str, "[at %u:%u][", code_pos.line, code_pos.column);
|
||||||
@ -56,10 +55,8 @@ void _Compiler_setError(Compiler* cmp, cstr context, cstr format, ...){
|
|||||||
Compiler_setError(cmp, FORMAT, ##__VA_ARGS__);\
|
Compiler_setError(cmp, FORMAT, ##__VA_ARGS__);\
|
||||||
}
|
}
|
||||||
|
|
||||||
char* Compiler_extractTokenStr(Compiler* cmp, Token t){
|
str Compiler_constructTokenStr(Compiler* cmp, Token t){
|
||||||
char* s = malloc(t.length + 1);
|
str s = str_construct((char*)(cmp->code.data + t.begin), t.length, false);
|
||||||
memcpy(s, cmp->code, t.length);
|
|
||||||
s[t.length] = 0;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,37 +72,34 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name,
|
|||||||
if(f == NULL)
|
if(f == NULL)
|
||||||
returnError("ERROR: can't open file '%s'", source_file_name);
|
returnError("ERROR: can't open file '%s'", source_file_name);
|
||||||
|
|
||||||
List_u8 buf = List_u8_alloc(64 * 1024);
|
StringBuilder sb = StringBuilder_alloc(64 * 1024);
|
||||||
int ret;
|
int ret;
|
||||||
while((ret = fgetc(f)) != EOF) {
|
while((ret = fgetc(f)) != EOF) {
|
||||||
List_u8_push(&buf, ret);
|
StringBuilder_append_char(&sb, ret);
|
||||||
}
|
}
|
||||||
if(ferror(f)){
|
if(ferror(f)){
|
||||||
free(buf.data);
|
StringBuilder_free(&sb);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
returnError("can't read file '%s'", source_file_name);
|
returnError("can't read file '%s'", source_file_name);
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if(buf.len == 0){
|
if(sb.buffer.len == 0){
|
||||||
free(buf.data);
|
StringBuilder_free(&sb);
|
||||||
fclose(f);
|
|
||||||
returnError("soucre file is empty");
|
returnError("soucre file is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp->code = (char*)buf.data;
|
cmp->code = str_copy(StringBuilder_getStr(&sb));
|
||||||
cmp->code_len = buf.len;
|
StringBuilder_free(&sb);
|
||||||
List_u8_push(&buf, 0);
|
|
||||||
|
|
||||||
f = fopen(out_file_name, "wb");
|
f = fopen(out_file_name, "wb");
|
||||||
if(f == NULL){
|
if(f == NULL){
|
||||||
free(buf.data);
|
|
||||||
returnError("ERROR: can't open file '%s'", out_file_name);
|
returnError("ERROR: can't open file '%s'", out_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_log){
|
if(debug_log){
|
||||||
printf("----------------------------------[%s]---------------------------------\n", source_file_name);
|
printf("----------------------------------[%s]---------------------------------\n", source_file_name);
|
||||||
fputs(cmp->code, stdout);
|
fputs(cmp->code.data, stdout);
|
||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +114,11 @@ bool Compiler_compile(Compiler* cmp, cstr source_file_name, cstr out_file_name,
|
|||||||
Token t = cmp->tokens.data[i];
|
Token t = cmp->tokens.data[i];
|
||||||
CodePos pos = Compiler_getLineAndColumn(cmp, t.begin);
|
CodePos pos = Compiler_getLineAndColumn(cmp, t.begin);
|
||||||
char* tokstr = malloc(4096);
|
char* tokstr = malloc(4096);
|
||||||
strncpy(tokstr, cmp->code + t.begin, t.length);
|
strncpy(tokstr, cmp->code.data + t.begin, t.length);
|
||||||
tokstr[t.length] = 0;
|
tokstr[t.length] = 0;
|
||||||
printf("[l:%3u, c:%3u] %s '%s'\n",
|
printf("[l:%3u, c:%3u] %s '%s'\n",
|
||||||
pos.line, pos.column,
|
pos.line, pos.column,
|
||||||
TokenType_toString(t.type), tokstr);
|
TokenType_toString(t.type).data, tokstr);
|
||||||
free(tokstr);
|
free(tokstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
|
#include "../string/str.h"
|
||||||
#include "../collections/List.h"
|
#include "../collections/List.h"
|
||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
#include "AST.h"
|
#include "AST.h"
|
||||||
@ -14,8 +15,7 @@ typedef enum CompilerState {
|
|||||||
} CompilerState;
|
} CompilerState;
|
||||||
|
|
||||||
typedef struct Compiler {
|
typedef struct Compiler {
|
||||||
char* code;
|
str code;
|
||||||
u32 code_len;
|
|
||||||
u32 column; // > 0 if code parsing started
|
u32 column; // > 0 if code parsing started
|
||||||
u32 pos;
|
u32 pos;
|
||||||
CompilerState state;
|
CompilerState state;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
#include "../string/StringBuilder.h"
|
||||||
|
|
||||||
void _Compiler_setError(Compiler* cmp, cstr context, cstr format, ...) __attribute__((__format__(__printf__, 3, 4)));
|
void _Compiler_setError(Compiler* cmp, cstr context, cstr format, ...) __attribute__((__format__(__printf__, 3, 4)));
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ typedef struct CodePos {
|
|||||||
/// @param pos index in code buffer
|
/// @param pos index in code buffer
|
||||||
CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos);
|
CodePos Compiler_getLineAndColumn(Compiler* cmp, u32 pos);
|
||||||
|
|
||||||
char* Compiler_extractTokenStr(Compiler* cmp, Token t);
|
str Compiler_constructTokenStr(Compiler* cmp, Token t);
|
||||||
|
|
||||||
bool Compiler_lex(Compiler* cmp);
|
bool Compiler_lex(Compiler* cmp);
|
||||||
bool Compiler_parse(Compiler* cmp);
|
bool Compiler_parse(Compiler* cmp);
|
||||||
|
|||||||
@ -19,8 +19,8 @@ static void readCommentSingleLine(Compiler* cmp){
|
|||||||
cmp->column++;
|
cmp->column++;
|
||||||
cmp->pos++;
|
cmp->pos++;
|
||||||
|
|
||||||
while(cmp->pos < cmp->code_len){
|
while(cmp->pos < cmp->code.len){
|
||||||
c = cmp->code[cmp->pos];
|
c = cmp->code.data[cmp->pos];
|
||||||
// end of line
|
// end of line
|
||||||
if(c == '\r' || c == '\n'){
|
if(c == '\r' || c == '\n'){
|
||||||
tok.length = cmp->pos - tok.begin;
|
tok.length = cmp->pos - tok.begin;
|
||||||
@ -44,10 +44,10 @@ static void readCommentMultiLine(Compiler* cmp){
|
|||||||
cmp->column++;
|
cmp->column++;
|
||||||
cmp->pos++;
|
cmp->pos++;
|
||||||
|
|
||||||
while(cmp->pos < cmp->code_len){
|
while(cmp->pos < cmp->code.len){
|
||||||
c = cmp->code[cmp->pos];
|
c = cmp->code.data[cmp->pos];
|
||||||
// closing comment
|
// closing comment
|
||||||
if(cmp->pos > tok.begin + 3 && c == '/' && cmp->code[cmp->pos - 1] == '*') {
|
if(cmp->pos > tok.begin + 3 && c == '/' && cmp->code.data[cmp->pos - 1] == '*') {
|
||||||
tok.length = cmp->pos - tok.begin + 1;
|
tok.length = cmp->pos - tok.begin + 1;
|
||||||
List_Token_push(&cmp->tokens, tok);
|
List_Token_push(&cmp->tokens, tok);
|
||||||
return;
|
return;
|
||||||
@ -65,14 +65,14 @@ static void readCommentMultiLine(Compiler* cmp){
|
|||||||
|
|
||||||
static void readComment(Compiler* cmp){
|
static void readComment(Compiler* cmp){
|
||||||
char c; // '/'
|
char c; // '/'
|
||||||
if(cmp->pos + 1 == cmp->code_len){
|
if(cmp->pos + 1 == cmp->code.len){
|
||||||
setError(Error_endOfFile);
|
setError(Error_endOfFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = cmp->code[cmp->pos + 1];
|
c = cmp->code.data[cmp->pos + 1];
|
||||||
if(c == '\r' || c == '\n'){
|
if(c == '\r' || c == '\n'){
|
||||||
setError(Error_unexpectedCharacter(cmp->code[--cmp->pos]));
|
setError(Error_unexpectedCharacter(cmp->code.data[--cmp->pos]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,14 +91,14 @@ static void readLabel(Compiler* cmp){
|
|||||||
cmp->column++;
|
cmp->column++;
|
||||||
Token tok = Token_construct(TokenType_Label, cmp->pos, 0);
|
Token tok = Token_construct(TokenType_Label, cmp->pos, 0);
|
||||||
|
|
||||||
while(cmp->pos < cmp->code_len){
|
while(cmp->pos < cmp->code.len){
|
||||||
c = cmp->code[cmp->pos];
|
c = cmp->code.data[cmp->pos];
|
||||||
// end of line
|
// end of line
|
||||||
if(c == ':' || c == '\r' || c == '\n'){
|
if(c == ':' || c == '\r' || c == '\n'){
|
||||||
tok.length = cmp->pos - tok.begin;
|
tok.length = cmp->pos - tok.begin;
|
||||||
if(tok.length > 0)
|
if(tok.length > 0)
|
||||||
List_Token_push(&cmp->tokens, tok);
|
List_Token_push(&cmp->tokens, tok);
|
||||||
else setError(Error_unexpectedCharacter(cmp->code[--cmp->pos]));
|
else setError(Error_unexpectedCharacter(cmp->code.data[--cmp->pos]));
|
||||||
// cmp->line will be increased in lex()
|
// cmp->line will be increased in lex()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -125,12 +125,12 @@ static void readArguments(Compiler* cmp){
|
|||||||
Token tok = Token_construct(TokenType_Unset, cmp->pos, 0);
|
Token tok = Token_construct(TokenType_Unset, cmp->pos, 0);
|
||||||
char quot = '\0'; // quotation character of a string value
|
char quot = '\0'; // quotation character of a string value
|
||||||
|
|
||||||
while(cmp->pos < cmp->code_len){
|
while(cmp->pos < cmp->code.len){
|
||||||
c = cmp->code[cmp->pos];
|
c = cmp->code.data[cmp->pos];
|
||||||
|
|
||||||
// string argument reading
|
// string argument reading
|
||||||
if(quot != '\0'){
|
if(quot != '\0'){
|
||||||
if(c == quot && cmp->code[cmp->pos - 1] != '\\'){
|
if(c == quot && cmp->code.data[cmp->pos - 1] != '\\'){
|
||||||
quot = '\0';
|
quot = '\0';
|
||||||
}
|
}
|
||||||
else if(c == '\r' || c == '\n'){
|
else if(c == '\r' || c == '\n'){
|
||||||
@ -189,8 +189,8 @@ static void readInstruction(Compiler* cmp){
|
|||||||
cmp->pos++;
|
cmp->pos++;
|
||||||
cmp->column++;
|
cmp->column++;
|
||||||
|
|
||||||
while(cmp->pos < cmp->code_len){
|
while(cmp->pos < cmp->code.len){
|
||||||
char c = cmp->code[cmp->pos];
|
char c = cmp->code.data[cmp->pos];
|
||||||
// end of line
|
// end of line
|
||||||
if(c == '\r' || c == '\n' || c == ';'){
|
if(c == '\r' || c == '\n' || c == ';'){
|
||||||
tok.length = cmp->pos - tok.begin;
|
tok.length = cmp->pos - tok.begin;
|
||||||
@ -232,8 +232,8 @@ bool Compiler_lex(Compiler* cmp){
|
|||||||
cmp->state = CompilerState_Lexing;
|
cmp->state = CompilerState_Lexing;
|
||||||
cmp->column = 1;
|
cmp->column = 1;
|
||||||
|
|
||||||
while(cmp->pos < cmp->code_len){
|
while(cmp->pos < cmp->code.len){
|
||||||
char c = cmp->code[cmp->pos];
|
char c = cmp->code.data[cmp->pos];
|
||||||
switch(c){
|
switch(c){
|
||||||
// skip blank characters
|
// skip blank characters
|
||||||
case ' ': case '\t': case '\r': case '\n':
|
case ' ': case '\t': case '\r': case '\n':
|
||||||
@ -257,7 +257,7 @@ bool Compiler_lex(Compiler* cmp){
|
|||||||
if(cmp->state == CompilerState_Error)
|
if(cmp->state == CompilerState_Error)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
c = cmp->code[cmp->pos];
|
c = cmp->code.data[cmp->pos];
|
||||||
if(c == '\n')
|
if(c == '\n')
|
||||||
completeLine(cmp);
|
completeLine(cmp);
|
||||||
cmp->column++;
|
cmp->column++;
|
||||||
|
|||||||
@ -6,15 +6,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define setError_unexpectedToken(T) {\
|
#define setError_unexpectedToken(T) {\
|
||||||
char* tok_str = Compiler_extractTokenStr(cmp, T);\
|
str tok_str = str_copy(Compiler_constructTokenStr(cmp, T));\
|
||||||
cmp->pos = T.begin;\
|
cmp->pos = T.begin;\
|
||||||
Compiler_setError(cmp, "unexpected token '%s'", tok_str);\
|
Compiler_setError(cmp, "unexpected token '%s'", tok_str.data);\
|
||||||
free(tok_str);\
|
free(tok_str.data);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setError_unexpectedTokenChar(T, I) {\
|
#define setError_unexpectedTokenChar(T, I) {\
|
||||||
cmp->pos = T.begin + I;\
|
cmp->pos = T.begin + I;\
|
||||||
Compiler_setError(cmp, "unexpected token '%c'", cmp->code[cmp->pos]);\
|
Compiler_setError(cmp, "unexpected token '%c'", cmp->code.data[cmp->pos]);\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -30,62 +30,63 @@ static void List_u8_pushBytes(List_u8* l, void* value, u32 startIndex, u32 count
|
|||||||
|
|
||||||
static inline bool isVarSizeBits(u32 B) { return (B == 8 && B == 16 && B == 32 && B == 64); }
|
static inline bool isVarSizeBits(u32 B) { return (B == 8 && B == 16 && B == 32 && B == 64); }
|
||||||
|
|
||||||
static NULLABLE(u8*) resolveEscapeSequences(Compiler* cmp, cstr src){
|
static NULLABLE(str) resolveEscapeSequences(Compiler* cmp, str src){
|
||||||
u32 len = strlen(src);
|
StringBuilder sb = StringBuilder_alloc(src.len);
|
||||||
List_u8 resolved = List_u8_alloc(len);
|
|
||||||
char c;
|
char c;
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
for(u32 i = 0; i < len; i++){
|
for(u32 i = 0; i < src.len; i++){
|
||||||
c = src[i];
|
c = src.data[i];
|
||||||
if(c == '\\'){
|
if(c == '\\'){
|
||||||
escaped = !escaped;
|
escaped = !escaped;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!escaped){
|
if(!escaped){
|
||||||
List_u8_push(&resolved, c);
|
StringBuilder_append_char(&sb, c);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// escape codes
|
// escape codes
|
||||||
switch(c){
|
switch(c){
|
||||||
case '0':
|
case '0':
|
||||||
List_u8_push(&resolved, '\0');
|
StringBuilder_append_char(&sb, '\0');
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
List_u8_push(&resolved, '\n');
|
StringBuilder_append_char(&sb, '\n');
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
List_u8_push(&resolved, '\r');
|
StringBuilder_append_char(&sb, '\r');
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
List_u8_push(&resolved, '\t');
|
StringBuilder_append_char(&sb, '\t');
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
List_u8_push(&resolved, '\e');
|
StringBuilder_append_char(&sb, '\e');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setError_unexpectedTokenChar(cmp->tokens.data[cmp->tok_i], i);
|
setError_unexpectedTokenChar(cmp->tokens.data[cmp->tok_i], i);
|
||||||
free(resolved.data);
|
StringBuilder_free(&sb);
|
||||||
return NULL;
|
return str_null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolved.data;
|
return StringBuilder_getStr(&sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parseDataDefinition(Compiler* cmp, char* instr_name, DataDefinition* ddf){
|
static void parseDataDefinition(Compiler* cmp, str instr_name, DataDefinition* ddf){
|
||||||
i32 _element_size_bits;
|
i32 _element_size_bits;
|
||||||
if(sscanf(instr_name, "const%i", &_element_size_bits) != 1 || !isVarSizeBits(_element_size_bits)){
|
str _instr_name_zero_terminated = str_copy(instr_name);
|
||||||
|
if(sscanf(_instr_name_zero_terminated.data, "const%i", &_element_size_bits) != 1 || !isVarSizeBits(_element_size_bits)){
|
||||||
|
free(_instr_name_zero_terminated.data);
|
||||||
setError(Error_BitSize);
|
setError(Error_BitSize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
free(_instr_name_zero_terminated.data);
|
||||||
ddf->element_size = _element_size_bits / 8;
|
ddf->element_size = _element_size_bits / 8;
|
||||||
|
|
||||||
Token tok = cmp->tokens.data[++cmp->tok_i];
|
Token tok = cmp->tokens.data[++cmp->tok_i];
|
||||||
char* tok_str = Compiler_extractTokenStr(cmp, tok);
|
str tok_str = Compiler_constructTokenStr(cmp, tok);
|
||||||
u8* processed_str = NULL;
|
str processed_str = str_null;
|
||||||
u32 len = 0;
|
|
||||||
ddf->name = tok_str;
|
ddf->name = tok_str;
|
||||||
|
|
||||||
while(++cmp->tok_i < cmp->tokens.len){
|
while(++cmp->tok_i < cmp->tokens.len){
|
||||||
@ -98,37 +99,38 @@ static void parseDataDefinition(Compiler* cmp, char* instr_name, DataDefinition*
|
|||||||
// skip comments
|
// skip comments
|
||||||
break;
|
break;
|
||||||
case TokenType_Number:
|
case TokenType_Number:
|
||||||
tok_str = Compiler_extractTokenStr(cmp, tok);
|
tok_str = Compiler_constructTokenStr(cmp, tok);
|
||||||
if(cstr_seekChar(tok_str, '.', 0, -1) != -1){
|
processed_str = str_copy(tok_str);
|
||||||
f64 f = atof(tok_str);
|
if(str_seekChar(tok_str, '.', 0) != -1){
|
||||||
|
f64 f = atof(tok_str.data);
|
||||||
List_u8_pushBytes(&ddf->data, &f, 8 - ddf->element_size, ddf->element_size);
|
List_u8_pushBytes(&ddf->data, &f, 8 - ddf->element_size, ddf->element_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
i64 i = atoll(tok_str);
|
i64 i = atoll(tok_str.data);
|
||||||
List_u8_pushBytes(&ddf->data, &i, 8 - ddf->element_size, ddf->element_size);
|
List_u8_pushBytes(&ddf->data, &i, 8 - ddf->element_size, ddf->element_size);
|
||||||
}
|
}
|
||||||
|
free(processed_str.data);
|
||||||
break;
|
break;
|
||||||
case TokenType_Char:
|
case TokenType_Char:
|
||||||
tok.begin += 1;
|
tok.begin += 1;
|
||||||
tok.length -= 2;
|
tok.length -= 2;
|
||||||
tok_str = Compiler_extractTokenStr(cmp, tok);
|
tok_str = Compiler_constructTokenStr(cmp, tok);
|
||||||
processed_str = resolveEscapeSequences(cmp, tok_str);
|
processed_str = resolveEscapeSequences(cmp, tok_str);
|
||||||
free(tok_str);
|
|
||||||
len = strlen((char*)processed_str);
|
if(processed_str.len != ddf->element_size){
|
||||||
if(len != ddf->element_size){
|
setError("can't fit char of size %i in %u bit variable", processed_str.len, _element_size_bits);
|
||||||
setError("can't fit char of size %i in %u bit variable", len, _element_size_bits);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List_u8_pushBytes(&ddf->data, processed_str, 0, len);
|
List_u8_pushBytes(&ddf->data, processed_str.data, 0, processed_str.len);
|
||||||
|
free(processed_str.data);
|
||||||
break;
|
break;
|
||||||
case TokenType_String:
|
case TokenType_String:
|
||||||
tok.begin += 1;
|
tok.begin += 1;
|
||||||
tok.length -= 2;
|
tok.length -= 2;
|
||||||
tok_str = Compiler_extractTokenStr(cmp, tok);
|
tok_str = Compiler_constructTokenStr(cmp, tok);
|
||||||
processed_str = resolveEscapeSequences(cmp, tok_str);
|
processed_str = resolveEscapeSequences(cmp, tok_str);
|
||||||
free(tok_str);
|
List_u8_pushBytes(&ddf->data, processed_str.data, 0, processed_str.len);
|
||||||
len = strlen((char*)processed_str);
|
free(processed_str.data);
|
||||||
List_u8_pushBytes(&ddf->data, processed_str, 0, len);
|
|
||||||
break;
|
break;
|
||||||
case TokenType_OperationEnd:
|
case TokenType_OperationEnd:
|
||||||
return;
|
return;
|
||||||
@ -140,7 +142,7 @@ static void parseDataDefinition(Compiler* cmp, char* instr_name, DataDefinition*
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void parseOperation(Compiler* cmp, char* instr_name, Operation* operPtr){
|
static void parseOperation(Compiler* cmp, str instr_name, Operation* operPtr){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,14 +164,14 @@ bool Compiler_parse(Compiler* cmp){
|
|||||||
case TokenType_Label:
|
case TokenType_Label:
|
||||||
// create new section
|
// create new section
|
||||||
sec = List_Section_expand(&cmp->ast.sections, 1);
|
sec = List_Section_expand(&cmp->ast.sections, 1);
|
||||||
Section_init(sec, Compiler_extractTokenStr(cmp, tok));
|
Section_init(sec, Compiler_constructTokenStr(cmp, tok));
|
||||||
break;
|
break;
|
||||||
case TokenType_Instruction:
|
case TokenType_Instruction:
|
||||||
if(sec == NULL)
|
if(sec == NULL)
|
||||||
returnError("no section");
|
returnError("no section");
|
||||||
char* instr_name = Compiler_extractTokenStr(cmp, tok);
|
str instr_name = Compiler_constructTokenStr(cmp, tok);
|
||||||
// data definition starts with const
|
// data definition starts with const
|
||||||
if(cstr_seek(instr_name, "const", 0, 1)){
|
if(str_startsWith(instr_name, STR("const"))){
|
||||||
DataDefinition* dataDefPtr = List_DataDefinition_expand(&sec->data, 1);
|
DataDefinition* dataDefPtr = List_DataDefinition_expand(&sec->data, 1);
|
||||||
parseDataDefinition(cmp, instr_name, dataDefPtr);
|
parseDataDefinition(cmp, instr_name, dataDefPtr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,22 +2,22 @@
|
|||||||
|
|
||||||
List_define(Token);
|
List_define(Token);
|
||||||
|
|
||||||
static cstr _TokenType_str[] = {
|
static str _TokenType_str[] = {
|
||||||
"Unset",
|
STR("Unset"),
|
||||||
"SingleLineComment",
|
STR("SingleLineComment"),
|
||||||
"MultiLineComment",
|
STR("MultiLineComment"),
|
||||||
"Instruction",
|
STR("Instruction"),
|
||||||
"Label",
|
STR("Label"),
|
||||||
"Number",
|
STR("Number"),
|
||||||
"Char",
|
STR("Char"),
|
||||||
"String",
|
STR("String"),
|
||||||
"Name",
|
STR("Name"),
|
||||||
"NamedDataPointer",
|
STR("NamedDataPointer"),
|
||||||
"NamedDataSize"
|
STR("NamedDataSize")
|
||||||
};
|
};
|
||||||
|
|
||||||
cstr TokenType_toString(TokenType t){
|
str TokenType_toString(TokenType t){
|
||||||
if(t >= ARRAY_SIZE(_TokenType_str))
|
if(t >= ARRAY_SIZE(_TokenType_str))
|
||||||
return "!!INDEX_ERROR!!";
|
return STR("!!INDEX_ERROR!!");
|
||||||
return _TokenType_str[t];
|
return _TokenType_str[t];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
|
#include "../string/str.h"
|
||||||
#include "../collections/List.h"
|
#include "../collections/List.h"
|
||||||
|
|
||||||
typedef enum TokenType {
|
typedef enum TokenType {
|
||||||
@ -17,7 +18,7 @@ typedef enum TokenType {
|
|||||||
TokenType_OperationEnd, // EOL or EOF or ;
|
TokenType_OperationEnd, // EOL or EOF or ;
|
||||||
} TokenType;
|
} TokenType;
|
||||||
|
|
||||||
cstr TokenType_toString(TokenType t);
|
str TokenType_toString(TokenType t);
|
||||||
|
|
||||||
typedef struct Token {
|
typedef struct Token {
|
||||||
u32 begin; // some index in Compiler->code
|
u32 begin; // some index in Compiler->code
|
||||||
|
|||||||
@ -19,13 +19,13 @@ typedef enum __attribute__((__packed__)) Opcode {
|
|||||||
} Opcode;
|
} Opcode;
|
||||||
|
|
||||||
typedef struct Instruction {
|
typedef struct Instruction {
|
||||||
cstr name;
|
str name;
|
||||||
InstructionImplFunc_t implementation;
|
InstructionImplFunc_t implementation;
|
||||||
Opcode opcode;
|
Opcode opcode;
|
||||||
} Instruction;
|
} Instruction;
|
||||||
|
|
||||||
#define Instruction_construct(NAME) {\
|
#define Instruction_construct(NAME) {\
|
||||||
.name = #NAME, \
|
.name = STR(#NAME), \
|
||||||
.implementation = NAME##_impl, \
|
.implementation = NAME##_impl, \
|
||||||
.opcode = Opcode_##NAME\
|
.opcode = Opcode_##NAME\
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ i32 main(const i32 argc, cstr* argv){
|
|||||||
for(u8 opcode = 0; opcode < 255; opcode++){
|
for(u8 opcode = 0; opcode < 255; opcode++){
|
||||||
const Instruction* instr = Instruction_getByOpcode(opcode);
|
const Instruction* instr = Instruction_getByOpcode(opcode);
|
||||||
if(instr != NULL){
|
if(instr != NULL){
|
||||||
printf("%02X %s\n", opcode, instr->name);
|
printf("%02X %s\n", opcode, instr->name.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user