diff --git a/sources/kernel/syscalls.c b/sources/kernel/syscalls.c index 4447ead01..3b64dc05e 100644 --- a/sources/kernel/syscalls.c +++ b/sources/kernel/syscalls.c @@ -518,9 +518,9 @@ BrResult syscall_dispatch(BrSyscall syscall, BrArg args) { log$("Syscall: Task({}): {}({#p}) -> {}", task_self()->id, - str$(br_syscall_to_string(syscall)), + str$(br_syscall_to_str(syscall)), args, - str$(br_result_to_string(result))); + str$(br_result_to_str(result))); } task_end_syscall(); diff --git a/sources/libs/bal/abi/helpers.c b/sources/libs/bal/abi/helpers.c index dc51529ca..c803f7e90 100644 --- a/sources/libs/bal/abi/helpers.c +++ b/sources/libs/bal/abi/helpers.c @@ -1,7 +1,7 @@ #include #include -char const *br_syscall_to_string(BrSyscall syscall) +char const *br_syscall_to_str(BrSyscall syscall) { static char const *SYSCALL_NAMES[] = { #define ITER(SYSCALL) #SYSCALL, @@ -17,7 +17,7 @@ char const *br_syscall_to_string(BrSyscall syscall) return SYSCALL_NAMES[syscall]; } -char const *br_result_to_string(BrResult result) +char const *br_result_to_str(BrResult result) { static char const *RESULT_NAMES[] = { #define ITER(RESULT) #RESULT, diff --git a/sources/libs/bal/abi/helpers.h b/sources/libs/bal/abi/helpers.h index c811f024d..700d6b8e2 100644 --- a/sources/libs/bal/abi/helpers.h +++ b/sources/libs/bal/abi/helpers.h @@ -2,9 +2,9 @@ #include -char const *br_syscall_to_string(BrSyscall syscall); +char const *br_syscall_to_str(BrSyscall syscall); -char const *br_result_to_string(BrResult result); +char const *br_result_to_str(BrResult result); Error br_result_to_error(BrResult result); diff --git a/sources/libs/brutal-base/slice.h b/sources/libs/brutal-base/slice.h index 94fa721d0..ad6510ffc 100644 --- a/sources/libs/brutal-base/slice.h +++ b/sources/libs/brutal-base/slice.h @@ -4,32 +4,38 @@ typedef struct { + void const *buf; size_t len; + size_t size; - void const *buf; } SliceImpl; #define slice_impl$(SLICE) \ (SliceImpl) { .len = (SLICE).len, .size = sizeof(*(SLICE).buf), .buf = (SLICE).buf, } -#define InlineBuf(T) \ - struct \ - { \ - size_t len; \ - T buf[]; \ - } - #define Slice(T) \ struct \ { \ - size_t len; \ T const *buf; \ + size_t len; \ } typedef Slice(void) VoidSlice; #define slice$(type, buffer, size) \ - (type) { .len = size, .buf = buffer } + (type) { .buf = buffer, .len = size } #define slice_array$(type, buffer) \ - (type) { .len = sizeof(buffer) / sizeof(*buffer), .buf = &(buffer) } + (type) { .buf = (buffer), .len = sizeof(buffer) / sizeof(*buffer), } + +#define slice_begin$(SLICE) ((SLICE).buf) + +#define slice_end$(SLICE) ((SLICE).buf + (SLICE).len) + +#define slice_foreach$(VAR, SELF) \ + if ((SELF).len) \ + for (typeof((SELF).buf) VAR = slice_begin$(SELF); VAR != slice_end$(SELF); VAR++) + +#define slice_foreach_rev$(VAR, SELF) \ + if ((SELF).len) \ + for (typeof((SELF).buf) VAR = slice_end$(SELF) - 1; VAR >= slice_begin$(SELF); VAR--) diff --git a/sources/libs/brutal-debug/assert.h b/sources/libs/brutal-debug/assert.h index 2a9f1aca4..caaf95f6c 100644 --- a/sources/libs/brutal-debug/assert.h +++ b/sources/libs/brutal-debug/assert.h @@ -22,14 +22,14 @@ } \ }) -#define assert_br_success(EXPR) ( \ - { \ - BrResult __value = (EXPR); \ - \ - if (UNLIKELY(__value != BR_SUCCESS)) \ - { \ - panic$("{} is not equal to BR_SUCCESS (but is equal to: '{}') ", #EXPR, br_result_to_string(__value)); \ - } \ +#define assert_br_success(EXPR) ( \ + { \ + BrResult __value = (EXPR); \ + \ + if (UNLIKELY(__value != BR_SUCCESS)) \ + { \ + panic$("{} is not equal to BR_SUCCESS (but is equal to: '{}') ", #EXPR, br_result_to_str(__value)); \ + } \ }) #define assert_falsity(EXPR) ( \ diff --git a/sources/libs/brutal-ds/vec.h b/sources/libs/brutal-ds/vec.h index c97536bfa..9eb1886c0 100644 --- a/sources/libs/brutal-ds/vec.h +++ b/sources/libs/brutal-ds/vec.h @@ -150,6 +150,10 @@ void vec_swap_impl(VecImpl *impl, int idx1, int idx2); if ((SELF)->len) \ for (typeof((SELF)->data) VAR = vec_begin(SELF); VAR != vec_end(SELF); VAR++) +#define vec_foreach_rev(VAR, SELF) \ + if ((SELF)->len) \ + for (typeof((SELF)->data) VAR = vec_end(SELF) - 1; VAR >= vec_begin(SELF); VAR--) + #define vec_foreach_idx(IDX, VAR, SELF) \ if ((SELF)->len) \ for (int IDX = 0; IDX < (SELF)->len; IDX++) \ diff --git a/sources/libs/brutal-fmt/fmt.h b/sources/libs/brutal-fmt/fmt.h index a80a78ecf..cc98a7c35 100644 --- a/sources/libs/brutal-fmt/fmt.h +++ b/sources/libs/brutal-fmt/fmt.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include "case.h" diff --git a/sources/libs/brutal-fmt/funcs.h b/sources/libs/brutal-fmt/funcs.h index 023c9c1ac..ba49f55a7 100644 --- a/sources/libs/brutal-fmt/funcs.h +++ b/sources/libs/brutal-fmt/funcs.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "fmt.h" IoResult fmt_format(IoWriter writer, Str format, AnyVa args); diff --git a/sources/libs/brutal-parse/lex.c b/sources/libs/brutal-parse/lex.c index 317953dbe..8bc1a3af5 100644 --- a/sources/libs/brutal-parse/lex.c +++ b/sources/libs/brutal-parse/lex.c @@ -3,6 +3,11 @@ #include "lex.h" Lex lex(Scan *scan, LexFn *fn, Alloc *alloc) +{ + return lex_tu(scan, fn, alloc, -1); +} + +Lex lex_tu(Scan *scan, LexFn *fn, Alloc *alloc, int translation_unit) { Lex self = {}; vec_init(&self.lexemes, alloc); @@ -10,8 +15,17 @@ Lex lex(Scan *scan, LexFn *fn, Alloc *alloc) while (!scan_ended(scan)) { scan_begin(scan); - - Lexeme l = {fn(scan), scan_end(scan)}; + int begin = scan->head; + + Lexeme l = { + .type = fn(scan), + .str = scan_end(scan), + (SrcRef){ + .translation_unit = translation_unit, + .begin = begin, + .end = scan->head, + }, + }; if (l.type == LEXEME_INVALID) { @@ -50,6 +64,11 @@ Lexeme lex_peek(Lex *self, int offset) return (Lexeme){ LEXEME_EOF, str$(""), + (SrcRef){ + .begin = self->head + offset, + .end = self->head + offset, + .translation_unit = -1, + }, }; } @@ -146,3 +165,17 @@ bool lex_ok(Lex *self) { return !self->has_error; } + +SrcRef lex_src_ref(Lex *lex, int begin, int end) +{ + Lexeme first = lex->lexemes.data[begin]; + Lexeme last = lex->lexemes.data[end]; + + SrcRef cref = { + .begin = first.pos.begin, + .end = last.pos.end, + .translation_unit = first.pos.translation_unit, + }; + + return cref; +} diff --git a/sources/libs/brutal-parse/lex.h b/sources/libs/brutal-parse/lex.h index a6cc13c4a..e5767b980 100644 --- a/sources/libs/brutal-parse/lex.h +++ b/sources/libs/brutal-parse/lex.h @@ -36,6 +36,8 @@ typedef Str LexToStrFn(LexemeType type); Lex lex(Scan *scan, LexFn *fn, Alloc *alloc); +Lex lex_tu(Scan *scan, LexFn *fn, Alloc *alloc, int translation_unit); + Lex lex_from_lexeme(Lexemes *from); void lex_deinit(Lex *self); @@ -65,3 +67,5 @@ void lex_throw(Lex *self, Str message); bool lex_expect(Lex *self, LexemeType type); bool lex_ok(Lex *self); + +SrcRef lex_src_ref(Lex *lex, int begin, int end); diff --git a/sources/libs/brutal-parse/lexeme.h b/sources/libs/brutal-parse/lexeme.h index fa027381c..f6c4e6dc5 100644 --- a/sources/libs/brutal-parse/lexeme.h +++ b/sources/libs/brutal-parse/lexeme.h @@ -2,6 +2,7 @@ #include +#include "ref.h" #define LEXEME_EOF (-1) #define LEXEME_INVALID (-2) @@ -11,6 +12,7 @@ typedef struct { LexemeType type; Str str; + SrcRef pos; } Lexeme; #define lexeme$(TYPE, STR) \ diff --git a/sources/libs/brutal-parse/nums.c b/sources/libs/brutal-parse/nums.c index f9fca00ab..6e0ef83ba 100644 --- a/sources/libs/brutal-parse/nums.c +++ b/sources/libs/brutal-parse/nums.c @@ -146,26 +146,26 @@ bool scan_next_double(Scan *self, double *value) #endif -bool str_to_uint(Str string, unsigned long *value) +bool str_to_uint(Str str, unsigned long *value) { Scan scan = {0}; - scan_init(&scan, string); + scan_init(&scan, str); return scan_next_uint(&scan, value); } -bool str_to_int(Str string, long *value) +bool str_to_int(Str str, long *value) { Scan scan = {0}; - scan_init(&scan, string); + scan_init(&scan, str); return scan_next_int(&scan, value); } #ifndef __freestanding__ -bool str_to_float(Str string, double *value) +bool str_to_float(Str str, double *value) { Scan scan = {0}; - scan_init(&scan, string); + scan_init(&scan, str); return scan_next_double(&scan, value); } diff --git a/sources/libs/brutal-parse/nums.h b/sources/libs/brutal-parse/nums.h index b5e43f42d..bf23231ad 100644 --- a/sources/libs/brutal-parse/nums.h +++ b/sources/libs/brutal-parse/nums.h @@ -16,12 +16,12 @@ bool scan_next_double(Scan *self, double *value); #endif -bool str_to_uint(Str string, unsigned long *value); +bool str_to_uint(Str str, unsigned long *value); -bool str_to_int(Str string, long *value); +bool str_to_int(Str str, long *value); #ifndef __freestanding__ -bool str_to_float(Str string, double *value); +bool str_to_float(Str str, double *value); #endif diff --git a/sources/libs/brutal-parse/ref.c b/sources/libs/brutal-parse/ref.c new file mode 100644 index 000000000..fbacb0e06 --- /dev/null +++ b/sources/libs/brutal-parse/ref.c @@ -0,0 +1,37 @@ +#include "ref.h" + +void scan_srcref_info(SrcRef ref, SrcFilePosInfo *info, Str const src) +{ + int begin = ref.begin; + int end = ref.end; + int line_len; + + int line_number_start = str_count_chr(str_sub(src, 0, begin), '\n') + 1; + int line_number_end = str_count_chr(str_sub(src, 0, end), '\n') + 1; + int line_start = str_last_chr(str_sub(src, 0, begin), '\n') + 1; + int line_end = str_first_chr(str_sub(src, end, src.len), '\n') + end; + bool is_multiline = line_number_start != line_number_end; + + if (!is_multiline) + { + line_len = str_first_chr(str_sub(src, line_start, src.len), '\n'); + } + else + { + line_len = str_last_chr(str_sub(src, line_start, line_end + 1), '\n'); + } + + if (line_len == -1) + { + line_len = src.len; + } + + *info = (SrcFilePosInfo){ + .is_multiline = is_multiline, + .char_line_len = line_len, + .char_line_end = line_end, + .char_line_start = line_start, + .line_number_end = line_number_end, + .line_number_start = line_number_start, + }; +} diff --git a/sources/libs/brutal-parse/ref.h b/sources/libs/brutal-parse/ref.h new file mode 100644 index 000000000..b42bdbcde --- /dev/null +++ b/sources/libs/brutal-parse/ref.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +typedef struct +{ + int translation_unit; + int begin; + int end; +} SrcRef; + +typedef struct +{ + int line_number_start; // the number of the line at the start + int line_number_end; // the number of the line at the end + int char_line_start; // the starting character index aligned by a line + int char_line_end; // the last character index aligned by a line + int char_line_len; // the length of the line(s) + bool is_multiline; // if the range is represented by multiple or a single line +} SrcFilePosInfo; + +void scan_srcref_info(SrcRef ref, SrcFilePosInfo *info, Str const src); diff --git a/sources/libs/brutal-parse/report.c b/sources/libs/brutal-parse/report.c new file mode 100644 index 000000000..ec8704033 --- /dev/null +++ b/sources/libs/brutal-parse/report.c @@ -0,0 +1,176 @@ +#include + +#include "report.h" + +void parse_reports_init(ParseReports *self, Alloc *alloc) +{ + vec_init(&self->reports, alloc); + self->alloc = alloc; +} + +void parse_reports_deinit(ParseReports *self) +{ + vec_deinit(&self->reports); +} + +int parse_report_impl(ParseReports *self, Str id, ParseReportLevel level, SrcRef ref, Str msg) +{ + ParseReport rep = { + .level = level, + .report_user_id = str_dup(id, self->alloc), + .info = (ParseReportInfo){ + .msg = msg, + .ref = ref, + }, + .comments = {}, + }; + + vec_init(&rep.comments, self->alloc); + vec_push(&self->reports, rep); + return self->reports.len - 1; +} + +void parse_report_comment_impl(ParseReports *self, int report_id, SrcRef ref, Str msg) +{ + assert_lower_than(report_id, self->reports.len); + ParseReport *report = &self->reports.data[report_id]; + + vec_push(&report->comments, + ((ParseReportInfo){ + .ref = ref, + .msg = msg, + })); +} + +static void parse_report_line(Emit *out, Str src, SrcFilePosInfo info, bool only_first_line) +{ + Str line = str_sub(src, info.char_line_start, info.char_line_end); + + emit_fmt$(out, "{3d fg-blue} {fg-blue} ", info.line_number_start, "|"); + + if (info.is_multiline && !only_first_line) + { + emit_fmt$(out, "{fg-red} ", "/"); + } + + int line_number = info.line_number_start; + for (int i = 0; i < info.char_line_len; i++) + { + if (line.buf[i] == '\n') + { + if (only_first_line) + { + break; + } + line_number++; + emit_fmt$(out, "\n{3d fg-blue} {fg-blue} ", line_number, "|"); + + if (info.is_multiline) + { + emit_fmt$(out, "{fg-red} ", "|"); + } + } + else + { + char lined = (char)line.buf[i]; + if (lined == '\t') + { + lined = ' '; + } + emit_fmt$(out, "{}", lined); + } + } +} + +void parse_report_dump(ParseReport report, Emit *out, Scan const *source, Str filename) +{ + SrcRef src_ref = report.info.ref; + int begin = src_ref.begin; + int end = src_ref.end; + + if (report.level == PARSE_WARN) + { + emit_fmt$(out, "\n! warn: {fg-red}\n", report.info.msg); + } + else if (report.level == PARSE_ERR) + { + emit_fmt$(out, "\n!! {fg-red bold}({fg-red}): {bold}\n", "error", report.report_user_id, report.info.msg); + } + + Str src = str_n$(source->size, (char *)source->buf); + SrcFilePosInfo info; + scan_srcref_info(src_ref, &info, src); + // number of line from begin + emit_fmt$(out, "-> {fg-blue}:{}:{} \n", filename, info.line_number_start, begin - info.char_line_start); + + parse_report_line(out, src, info, false); + + if (!info.is_multiline) + { + emit_fmt$(out, "\n :"); + + for (int i = info.char_line_start; i < info.char_line_end; i++) + { + if (i > begin && i <= end) + { + emit_fmt$(out, "{fg-red}", "^"); + } + else + { + emit_fmt$(out, " "); + } + } + emit_fmt$(out, " {fg-red}", report.info.msg); + } + + vec_foreach(v, &report.comments) + { + + // if the comment is in the same line as the error, we don't need to print a separate line + bool is_comment_inline = + v->ref.begin >= info.char_line_start && + v->ref.end <= (info.char_line_end); + + SrcFilePosInfo subinfo = info; + + // if the comment is somewhere else in the code, we need to print the line + if (info.is_multiline || !is_comment_inline) + { + emit_fmt$(out, "\n"); + scan_srcref_info(v->ref, &subinfo, src); + parse_report_line(out, src, subinfo, true); + } + + emit_fmt$(out, "\n :"); + + for (int i = subinfo.char_line_start; i < m_min(subinfo.char_line_end, v->ref.end + 2); i++) + { + if (i > v->ref.begin && i <= v->ref.end) + { + emit_fmt$(out, "{fg-blue}", "-"); + } + else + { + emit_fmt$(out, " "); + } + } + + emit_fmt$(out, " {fg-blue}", v->msg); + } + + emit_fmt$(out, "\n"); +} + +int parse_reports_dump(ParseReports *self, Scan const *scan, Emit *out, Str buf_id) +{ + int has_error = 0; + vec_foreach(report, &self->reports) + { + if (report->level == PARSE_ERR) + { + has_error += 1; + } + parse_report_dump(*report, out, scan, buf_id); + } + return has_error; +} diff --git a/sources/libs/brutal-parse/report.h b/sources/libs/brutal-parse/report.h new file mode 100644 index 000000000..221e10678 --- /dev/null +++ b/sources/libs/brutal-parse/report.h @@ -0,0 +1,57 @@ + +#pragma once + +#include +#include + +#include "ref.h" +#include "scan.h" +typedef enum +{ + PARSE_REPORT_NONE, + PARSE_WARN, + PARSE_ERR, +} ParseReportLevel; + +typedef struct +{ + SrcRef ref; + Str msg; +} ParseReportInfo; + +typedef struct +{ + ParseReportLevel level; + ParseReportInfo info; + Str report_user_id; + Vec(ParseReportInfo) comments; +} ParseReport; + +typedef struct +{ + Alloc *alloc; + Vec(ParseReport) reports; +} ParseReports; + +void parse_reports_init(ParseReports *self, Alloc *alloc); + +void parse_reports_deinit(ParseReports *self); + +int parse_report_impl(ParseReports *self, Str id, ParseReportLevel level, SrcRef ref, Str msg); + +void parse_report_comment_impl(ParseReports *self, int report_id, SrcRef ref, Str msg); + +void parse_report_dump(ParseReport report, Emit *out, Scan const *source, Str filename); +int parse_reports_dump(ParseReports *self, Scan const *scan, Emit *out, Str buf_id); + +#define parse_report$(SELF, LEVEL, ID, REF, FMT, ...) \ + ({ \ + Str _report_str = fmt_str((SELF)->alloc, str$(FMT), any_va$(__VA_ARGS__)); \ + parse_report_impl((SELF), (ID), (LEVEL), (REF), _report_str); \ + }) + +#define parse_comment$(SELF, REPORT, REF, FMT, ...) \ + ({ \ + Str _report_str = fmt_str((SELF)->alloc, str$(FMT), any_va$(__VA_ARGS__)); \ + parse_report_comment_impl((SELF), (REPORT), (REF), _report_str); \ + }) diff --git a/sources/libs/brutal-parse/scan.c b/sources/libs/brutal-parse/scan.c index 5add8b84f..614908c5f 100644 --- a/sources/libs/brutal-parse/scan.c +++ b/sources/libs/brutal-parse/scan.c @@ -137,6 +137,20 @@ bool scan_skip_word(Scan *self, Str word) return true; } +bool scan_skip_word_nc(Scan *self, Str word) +{ + for (size_t i = 0; i < word.len; i++) + { + if (tolower(scan_peek(self, i)) != tolower(word.buf[i])) + { + return false; + } + } + + scan_next_n(self, word.len); + return true; +} + bool scan_skip_any(Scan *self, Str chars) { for (size_t i = 0; i < chars.len; i++) @@ -162,6 +176,20 @@ bool scan_skip_match(Scan *self, ScanMatch *match) return true; } +bool scan_skip_any_nc(Scan *self, Str chars) +{ + for (size_t i = 0; i < chars.len; i++) + { + if (tolower(scan_curr(self)) == tolower(chars.buf[i])) + { + scan_next(self); + return true; + } + } + + return false; +} + bool scan_eat(Scan *self, ScanMatch *match) { bool result = false; diff --git a/sources/libs/brutal-parse/scan.h b/sources/libs/brutal-parse/scan.h index 58c3934bf..c050f6bd1 100644 --- a/sources/libs/brutal-parse/scan.h +++ b/sources/libs/brutal-parse/scan.h @@ -103,10 +103,14 @@ bool scan_skip(Scan *self, char c); bool scan_skip_word(Scan *self, Str word); +bool scan_skip_word_nc(Scan *self, Str word); + bool scan_skip_any(Scan *self, Str chars); bool scan_skip_match(Scan *self, ScanMatch *match); +bool scan_skip_any_nc(Scan *self, Str chars); + bool scan_skip_space(Scan *self); bool scan_eat(Scan *self, ScanMatch *match); diff --git a/sources/libs/cc/ast/decl.h b/sources/libs/cc/ast/decl.h index aa0dcb229..2fe785bf9 100644 --- a/sources/libs/cc/ast/decl.h +++ b/sources/libs/cc/ast/decl.h @@ -7,9 +7,8 @@ typedef enum { - CDECL_NIL, - CDECL_EMPTY, + CDECL_TYPE, CDECL_VAR, CDECL_FUNC, @@ -34,10 +33,12 @@ typedef struct typedef struct _CDecl { + SrcRef ref; CDeclType type; CDeclAttr attr; Str name; CType sema_type; + union { struct diff --git a/sources/libs/cc/ast/expr.c b/sources/libs/cc/ast/expr.c deleted file mode 100644 index 7ca762554..000000000 --- a/sources/libs/cc/ast/expr.c +++ /dev/null @@ -1,140 +0,0 @@ -#include - -static const char *cop_type_to_str[COP_COUNT] = { - [COP_INVALID] = "invalid", - [COP_INC] = "++", - [COP_DEC] = "--", - [COP_ASSIGN] = "=", - [COP_ASSIGN_ADD] = "+=", - [COP_ASSIGN_SUB] = "-=", - [COP_ASSIGN_MULT] = "*=", - [COP_ASSIGN_DIV] = "/=", - [COP_ASSIGN_MOD] = "%=", - [COP_ASSIGN_BIT_AND] = "&=", - [COP_ASSIGN_BIT_OR] = "|=", - [COP_ASSIGN_BIT_XOR] = "^=", - [COP_ASSIGN_LSHIFT] = "<<=", - [COP_ASSIGN_RSHIFT] = ">>=", - [COP_ADD] = "+", - [COP_SUB] = "-", - [COP_MULT] = "*", - [COP_DIV] = "/", - [COP_MOD] = "%", - [COP_BIT_NOT] = "~", - [COP_BIT_AND] = "&", - [COP_BIT_OR] = "|", - [COP_BIT_XOR] = "^", - [COP_LSHIFT] = "<<", - [COP_RSHIFT] = ">>", - [COP_NOT] = "!", - [COP_AND] = "&&", - [COP_OR] = "||", - [COP_EQ] = "==", - [COP_NOT_EQ] = "!=", - [COP_LT] = "<", - [COP_GT] = ">", - [COP_LT_EQ] = "<=", - [COP_GT_EQ] = ">=", - [COP_INDEX] = "[", - [COP_DEREF] = "*", - [COP_REF] = "&", - [COP_ACCESS] = ".", - [COP_PTR_ACCESS] = "->", -}; - -Str cop_to_str(COp type) -{ - return str$(cop_type_to_str[type]); -} - -static const char *cexpr_type_to_str_raw[CEXPR_COUNT] = { - [CEXPR_EMPTY] = "empty", - [CEXPR_SELF] = "self", - [CEXPR_CONSTANT] = "constant", - [CEXPR_IDENT] = "identifier", - [CEXPR_PREFIX] = "prefix", - [CEXPR_INFIX] = "infix", - [CEXPR_POSTFIX] = "postfix", - [CEXPR_CALL] = "call", - [CEXPR_CAST] = "cast", - [CEXPR_TERNARY] = "ternary", - [CEXPR_INITIALIZER] = "initializer", - [CEXPR_LAMBDA] = "lambda", -}; - -Str cexpr_type_to_str(CExprType type) -{ - return str$(cexpr_type_to_str_raw[type]); -} - -static int cop_precedence_table[COP_COUNT] = { - [COP_INC] = 1, - [COP_DEC] = 1, - [COP_ASSIGN] = 14, - [COP_ASSIGN_ADD] = 14, - [COP_ASSIGN_SUB] = 14, - [COP_ASSIGN_MULT] = 14, - [COP_ASSIGN_DIV] = 14, - [COP_ASSIGN_MOD] = 14, - [COP_ASSIGN_BIT_AND] = 14, - [COP_ASSIGN_BIT_OR] = 14, - [COP_ASSIGN_BIT_XOR] = 14, - [COP_ASSIGN_LSHIFT] = 14, - [COP_ASSIGN_RSHIFT] = 14, - [COP_ADD] = 2, - [COP_SUB] = 2, - [COP_MULT] = 3, - [COP_DIV] = 3, - [COP_MOD] = 3, - [COP_BIT_NOT] = 2, - [COP_BIT_AND] = 8, - [COP_BIT_OR] = 10, - [COP_BIT_XOR] = 9, - [COP_LSHIFT] = 5, - [COP_RSHIFT] = 5, - [COP_NOT] = 2, - [COP_AND] = 12, - [COP_OR] = 11, - [COP_EQ] = 7, - [COP_NOT_EQ] = 7, - [COP_LT] = 6, - [COP_GT] = 6, - [COP_LT_EQ] = 6, - [COP_GT_EQ] = 6, - [COP_INDEX] = 1, - [COP_DEREF] = 2, - [COP_REF] = 2, - [COP_ACCESS] = 1, - [COP_PTR_ACCESS] = 1, -}; - -int cop_pre(COp cop) -{ - return cop_precedence_table[cop]; -} - -int cexpr_pre(CExpr *expr) -{ - switch (expr->type) - { - case CEXPR_PREFIX: - case CEXPR_POSTFIX: - case CEXPR_INFIX: - return cop_pre(expr->infix_.op); - - case CEXPR_IDENT: - case CEXPR_CONSTANT: - return 0; - - case CEXPR_CALL: - case CEXPR_CAST: - case CEXPR_INITIALIZER: - return 1; - - case CEXPR_TERNARY: - return 13; - - default: - return 0; - } -} diff --git a/sources/libs/cc/ast/expr.h b/sources/libs/cc/ast/expr.h index ce720b003..5276c10b1 100644 --- a/sources/libs/cc/ast/expr.h +++ b/sources/libs/cc/ast/expr.h @@ -97,11 +97,13 @@ typedef struct struct _CExpr { + SrcRef ref; CExprType type; CType sema_type; + union { - CVal constant_; /* instead of Cval holding sema_type the cexpr holds it */ + CVal constant_; Str ident_; struct @@ -149,13 +151,3 @@ struct _CExpr } lambda_; }; }; - -COp str_to_cop(Str str); - -Str cop_to_str(COp type); - -Str cexpr_type_to_str(CExprType type); - -int cop_pre(COp cop); - -int cexpr_pre(CExpr *expr); diff --git a/sources/libs/cc/ast/ref.h b/sources/libs/cc/ast/ref.h new file mode 100644 index 000000000..cf6b2d837 --- /dev/null +++ b/sources/libs/cc/ast/ref.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +/** + * @brief Change element to have a SrcRef with begin = begin and end = lex.head + * It is a macro because it is more simple to do something like this: + * ```c + * return with_ref$(if_stmt, begin, lex); + * ``` + * than this: + * ```c + * if_stmt.ref = lex_src_ref(if_stmt, begin, lex); + * return if_stmt; + * ``` + * @param element The ast element to change. + * @param begin Begin index of the ast element. + * @param lex The lexer at the end of the element. + */ +#define with_cref$(element, begin, lex) \ + ({ \ + typeof(element) __element = (element); \ + __element.ref = lex_src_ref((lex), (begin), (lex)->head); \ + __element; \ + }) diff --git a/sources/libs/cc/ast/stmt.c b/sources/libs/cc/ast/stmt.c deleted file mode 100644 index e56f93ee7..000000000 --- a/sources/libs/cc/ast/stmt.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -char const *cstmt_type_to_str_raw[] = { - [CSTMT_EMPTY] = "empty", - [CSTMT_DECL] = "declaration", - [CSTMT_EXPR] = "expression", - [CSTMT_BLOCK] = "block", - [CSTMT_IF] = "if", - [CSTMT_FOR] = "for", - [CSTMT_WHILE] = "while", - [CSTMT_DO] = "do", - [CSTMT_SWITCH] = "switch", - [CSTMT_RETURN] = "return", - [CSTMT_GOTO] = "goto", - [CSTMT_BREAK] = "break", - [CSTMT_CONTINUE] = "continue", - [CSTMT_LABEL] = "label", - [CSTMT_CASE] = "case", - [CSTMT_DEFAULT] = "default", -}; - -Str cstmt_type_to_str(CStmtType type) -{ - return str$(cstmt_type_to_str_raw[type]); -} diff --git a/sources/libs/cc/ast/stmt.h b/sources/libs/cc/ast/stmt.h index 6e14ff2f5..52e9044b9 100644 --- a/sources/libs/cc/ast/stmt.h +++ b/sources/libs/cc/ast/stmt.h @@ -1,8 +1,9 @@ #pragma once -#include #include #include +#include + typedef enum { CSTMT_INVALID, @@ -33,7 +34,9 @@ typedef struct _CStmt CStmt; struct _CStmt { + SrcRef ref; CStmtType type; + union { struct @@ -94,5 +97,3 @@ struct _CStmt } case_; }; }; - -Str cstmt_type_to_str(CStmtType type); diff --git a/sources/libs/cc/ast/type.c b/sources/libs/cc/ast/type.c deleted file mode 100644 index 3ab1aa416..000000000 --- a/sources/libs/cc/ast/type.c +++ /dev/null @@ -1,32 +0,0 @@ -#include - -const char *ctype_type_to_str[CTYPE_COUNT] = { - [CTYPE_INVALID] = "invalid", - - [CTYPE_ERROR] = "error", - [CTYPE_TAIL] = "tail", - - [CTYPE_VOID] = "void", - [CTYPE_AUTO] = "auto", - [CTYPE_BOOL] = "bool", - [CTYPE_PTR] = "", - [CTYPE_ARRAY] = "", - [CTYPE_SIGNED] = "signed", - [CTYPE_UNSIGNED] = "unsigned", - [CTYPE_FLOAT] = "float", - [CTYPE_STRUCT] = "struct", - [CTYPE_UNION] = "union", - [CTYPE_ENUM] = "enum", -}; - -Str ctype_to_str(CTypeType type) -{ - if (ctype_type_to_str[type]) - { - return str$(ctype_type_to_str[type]); - } - else - { - return str$(""); - } -} diff --git a/sources/libs/cc/ast/type.h b/sources/libs/cc/ast/type.h index 7078ac4fa..a85fb753e 100644 --- a/sources/libs/cc/ast/type.h +++ b/sources/libs/cc/ast/type.h @@ -8,7 +8,6 @@ typedef enum CTYPE_INVALID, CTYPE_TAIL, - CTYPE_ERROR, CTYPE_VOID, CTYPE_AUTO, @@ -17,9 +16,22 @@ typedef enum CTYPE_REF, CTYPE_PARENT, CTYPE_ARRAY, - CTYPE_SIGNED, - CTYPE_UNSIGNED, + + CTYPE_CHAR, + CTYPE_SHORT, + CTYPE_INT, + CTYPE_LONG, + CTYPE_LONGLONG, + + CTYPE_UCHAR, + CTYPE_USHORT, + CTYPE_UINT, + CTYPE_ULONG, + CTYPE_ULONGLONG, + CTYPE_FLOAT, + CTYPE_DOUBLE, + CTYPE_STRUCT, CTYPE_UNION, CTYPE_ENUM, @@ -45,17 +57,13 @@ typedef Vec(CTypeMember) CTypeMembers; struct _CType { + SrcRef ref; CTypeType type; CTypeAttr attr; Str name; union { - struct - { - int precision; - } signed_, unsigned_, float_; - struct { CType *subtype; @@ -96,7 +104,3 @@ struct _CTypeConst Str name; CVal value; }; - -typedef Slice(CType) CTypeSlice; - -Str ctype_to_str(CTypeType type); diff --git a/sources/libs/cc/ast/unit.c b/sources/libs/cc/ast/unit.c deleted file mode 100644 index ba99354ce..000000000 --- a/sources/libs/cc/ast/unit.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -bool cunit_contains_type(CUnit *context, Str name) -{ - vec_foreach_v(entry, &context->units) - { - if (entry.type == CUNIT_DECLARATION && str_eq(entry._decl.name, name)) - { - return true; - } - } - return false; -} diff --git a/sources/libs/cc/ast/unit.h b/sources/libs/cc/ast/unit.h index 1399d9d6f..1cfa6f321 100644 --- a/sources/libs/cc/ast/unit.h +++ b/sources/libs/cc/ast/unit.h @@ -22,7 +22,8 @@ typedef struct typedef enum { - CUNIT_NONE, + CUNIT_INVALID, + CUNIT_INCLUDE, CUNIT_PRAGMA, CUNIT_DECLARATION, @@ -31,7 +32,9 @@ typedef enum typedef struct { + SrcRef ref; CUnitType type; + union { CInclude _include; @@ -45,5 +48,3 @@ typedef struct { Vec(CUnitEntry) units; } CUnit; - -bool cunit_contains_type(CUnit *context, Str name); diff --git a/sources/libs/cc/ast/val.c b/sources/libs/cc/ast/val.c deleted file mode 100644 index b61c6c53b..000000000 --- a/sources/libs/cc/ast/val.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -const char *cval_type_to_str_raw[CVAL_COUNT] = - { - [CVAL_SIGNED] = "signed", - [CVAL_UNSIGNED] = "unsigned", - [CVAL_FLOAT] = "float", - [CVAL_STRING] = "string", -}; - -Str cval_type_to_str(CValType type) -{ - return str$(cval_type_to_str_raw[type]); -} diff --git a/sources/libs/cc/ast/val.h b/sources/libs/cc/ast/val.h index 96bbb5ad2..16046e927 100644 --- a/sources/libs/cc/ast/val.h +++ b/sources/libs/cc/ast/val.h @@ -1,31 +1,44 @@ #pragma once #include +#include -typedef int CSigned; -typedef unsigned int CUnsigned; +typedef int64_t CSigned; +typedef uint64_t CUnsigned; typedef enum { CVAL_INVALID, - CVAL_SIGNED, - CVAL_UNSIGNED, + CVAL_CHAR, + CVAL_SHORT, + CVAL_INT, + CVAL_LONG, + CVAL_LONGLONG, + + CVAL_UCHAR, + CVAL_USHORT, + CVAL_UINT, + CVAL_ULONG, + CVAL_ULONGLONG, + CVAL_FLOAT, + CVAL_DOUBLE, + CVAL_STRING, CVAL_COUNT, } CValType; -typedef struct +typedef struct _CVal { + SrcRef ref; CValType type; + union { CSigned signed_; CUnsigned unsigned_; double float_; - Str string_; + Str str_; }; } CVal; - -Str cval_type_to_str(CValType type); diff --git a/sources/libs/cc/builder/expr.c b/sources/libs/cc/builder/expr.c index bc2c422a7..f35959306 100644 --- a/sources/libs/cc/builder/expr.c +++ b/sources/libs/cc/builder/expr.c @@ -1,6 +1,148 @@ -#include #include +#include "expr.h" + +static const char *cop_type_to_str[COP_COUNT] = { + [COP_INVALID] = "invalid", + [COP_INC] = "++", + [COP_DEC] = "--", + [COP_ASSIGN] = "=", + [COP_ASSIGN_ADD] = "+=", + [COP_ASSIGN_SUB] = "-=", + [COP_ASSIGN_MULT] = "*=", + [COP_ASSIGN_DIV] = "/=", + [COP_ASSIGN_MOD] = "%=", + [COP_ASSIGN_BIT_AND] = "&=", + [COP_ASSIGN_BIT_OR] = "|=", + [COP_ASSIGN_BIT_XOR] = "^=", + [COP_ASSIGN_LSHIFT] = "<<=", + [COP_ASSIGN_RSHIFT] = ">>=", + [COP_ADD] = "+", + [COP_SUB] = "-", + [COP_MULT] = "*", + [COP_DIV] = "/", + [COP_MOD] = "%", + [COP_BIT_NOT] = "~", + [COP_BIT_AND] = "&", + [COP_BIT_OR] = "|", + [COP_BIT_XOR] = "^", + [COP_LSHIFT] = "<<", + [COP_RSHIFT] = ">>", + [COP_NOT] = "!", + [COP_AND] = "&&", + [COP_OR] = "||", + [COP_EQ] = "==", + [COP_NOT_EQ] = "!=", + [COP_LT] = "<", + [COP_GT] = ">", + [COP_LT_EQ] = "<=", + [COP_GT_EQ] = ">=", + [COP_INDEX] = "[", + [COP_DEREF] = "*", + [COP_REF] = "&", + [COP_ACCESS] = ".", + [COP_PTR_ACCESS] = "->", +}; + +Str cop_to_str(COp type) +{ + return str$(cop_type_to_str[type]); +} + +static const char *cexpr_to_str_raw[CEXPR_COUNT] = { + [CEXPR_EMPTY] = "empty", + [CEXPR_SELF] = "self", + [CEXPR_CONSTANT] = "constant", + [CEXPR_IDENT] = "identifier", + [CEXPR_PREFIX] = "prefix", + [CEXPR_INFIX] = "infix", + [CEXPR_POSTFIX] = "postfix", + [CEXPR_CALL] = "call", + [CEXPR_CAST] = "cast", + [CEXPR_TERNARY] = "ternary", + [CEXPR_INITIALIZER] = "initializer", + [CEXPR_LAMBDA] = "lambda", +}; + +Str cexpr_to_str(CExprType type) +{ + return str$(cexpr_to_str_raw[type]); +} + +static int cop_precedence_table[COP_COUNT] = { + [COP_INC] = 1, + [COP_DEC] = 1, + [COP_ASSIGN] = 14, + [COP_ASSIGN_ADD] = 14, + [COP_ASSIGN_SUB] = 14, + [COP_ASSIGN_MULT] = 14, + [COP_ASSIGN_DIV] = 14, + [COP_ASSIGN_MOD] = 14, + [COP_ASSIGN_BIT_AND] = 14, + [COP_ASSIGN_BIT_OR] = 14, + [COP_ASSIGN_BIT_XOR] = 14, + [COP_ASSIGN_LSHIFT] = 14, + [COP_ASSIGN_RSHIFT] = 14, + [COP_ADD] = 2, + [COP_SUB] = 2, + [COP_MULT] = 3, + [COP_DIV] = 3, + [COP_MOD] = 3, + [COP_BIT_NOT] = 2, + [COP_BIT_AND] = 8, + [COP_BIT_OR] = 10, + [COP_BIT_XOR] = 9, + [COP_LSHIFT] = 5, + [COP_RSHIFT] = 5, + [COP_NOT] = 2, + [COP_AND] = 12, + [COP_OR] = 11, + [COP_EQ] = 7, + [COP_NOT_EQ] = 7, + [COP_LT] = 6, + [COP_GT] = 6, + [COP_LT_EQ] = 6, + [COP_GT_EQ] = 6, + [COP_INDEX] = 1, + [COP_DEREF] = 2, + [COP_REF] = 2, + [COP_ACCESS] = 1, + [COP_PTR_ACCESS] = 1, +}; + +int cop_pre(COp cop) +{ + return cop_precedence_table[cop]; +} + +int cexpr_pre(CExpr *expr) +{ + switch (expr->type) + { + case CEXPR_PREFIX: + case CEXPR_POSTFIX: + case CEXPR_INFIX: + return cop_pre(expr->infix_.op); + + case CEXPR_IDENT: + case CEXPR_CONSTANT: + return 0; + + case CEXPR_CALL: + case CEXPR_CAST: + case CEXPR_INITIALIZER: + return 1; + + case CEXPR_TERNARY: + return 13; + + default: + return 0; + } +} + +/* --- Builder -------------------------------------------------------------- */ + CExpr cexpr_empty(void) { return (CExpr){ diff --git a/sources/libs/cc/builder/expr.h b/sources/libs/cc/builder/expr.h index a1fd69948..55129aba0 100644 --- a/sources/libs/cc/builder/expr.h +++ b/sources/libs/cc/builder/expr.h @@ -3,6 +3,18 @@ #include #include +COp str_to_cop(Str str); + +Str cop_to_str(COp type); + +Str cexpr_to_str(CExprType type); + +int cop_pre(COp cop); + +int cexpr_pre(CExpr *expr); + +/* --- Builder -------------------------------------------------------------- */ + CExpr cexpr_infix(CExpr left, COp type, CExpr right, Alloc *alloc); CExpr cexpr_empty(void); diff --git a/sources/libs/cc/builder/stmt.c b/sources/libs/cc/builder/stmt.c index c3f32271d..42f1cad20 100644 --- a/sources/libs/cc/builder/stmt.c +++ b/sources/libs/cc/builder/stmt.c @@ -1,6 +1,32 @@ #include #include +char const *cstmt_to_str_raw[] = { + [CSTMT_EMPTY] = "empty", + [CSTMT_DECL] = "declaration", + [CSTMT_EXPR] = "expression", + [CSTMT_BLOCK] = "block", + [CSTMT_IF] = "if", + [CSTMT_FOR] = "for", + [CSTMT_WHILE] = "while", + [CSTMT_DO] = "do", + [CSTMT_SWITCH] = "switch", + [CSTMT_RETURN] = "return", + [CSTMT_GOTO] = "goto", + [CSTMT_BREAK] = "break", + [CSTMT_CONTINUE] = "continue", + [CSTMT_LABEL] = "label", + [CSTMT_CASE] = "case", + [CSTMT_DEFAULT] = "default", +}; + +Str cstmt_to_str(CStmtType type) +{ + return str$(cstmt_to_str_raw[type]); +} + +/* --- Builder -------------------------------------------------------------- */ + CStmt cstmt_empty(void) { return (CStmt){ diff --git a/sources/libs/cc/builder/stmt.h b/sources/libs/cc/builder/stmt.h index f9b722b05..4ab556e9b 100644 --- a/sources/libs/cc/builder/stmt.h +++ b/sources/libs/cc/builder/stmt.h @@ -3,6 +3,10 @@ #include #include +Str cstmt_to_str(CStmtType type); + +/* --- Types --------------------------------------------------------------- */ + CStmt cstmt_empty(void); CStmt cstmt_decl(CDecl decl, Alloc *alloc); diff --git a/sources/libs/cc/builder/type.c b/sources/libs/cc/builder/type.c index f4bfca29c..0fa43d941 100644 --- a/sources/libs/cc/builder/type.c +++ b/sources/libs/cc/builder/type.c @@ -1,13 +1,55 @@ -#include #include +#include -CType ctype_error(void) +const char *ctype_type_to_str[CTYPE_COUNT] = { + [CTYPE_INVALID] = "", + [CTYPE_TAIL] = "", + + [CTYPE_VOID] = "void", + [CTYPE_AUTO] = "auto", + [CTYPE_BOOL] = "bool", + [CTYPE_PTR] = "", + [CTYPE_ARRAY] = "", + + [CTYPE_CHAR] = "char", + [CTYPE_SHORT] = "short", + [CTYPE_INT] = "int", + [CTYPE_LONG] = "long", + [CTYPE_LONGLONG] = "long long", + [CTYPE_UCHAR] = "unsigned char", + [CTYPE_USHORT] = "unsigned short", + [CTYPE_UINT] = "unsigned int", + [CTYPE_ULONG] = "unsigned long", + [CTYPE_ULONGLONG] = "unsigned long long", + [CTYPE_FLOAT] = "float", + [CTYPE_DOUBLE] = "double", + + [CTYPE_STRUCT] = "struct", + [CTYPE_UNION] = "union", + [CTYPE_ENUM] = "enum", +}; + +Str ctype_to_str(CType type) { - return (CType){ - .type = CTYPE_ERROR, - }; + if (ctype_type_to_str[type.type]) + { + return str$(ctype_type_to_str[type.type]); + } + else + { + return str$(""); + } +} + +CType ctype_to_unsigned(CType type) +{ + assert_truth(type.type >= CTYPE_CHAR && type.type <= CTYPE_ULONGLONG); + type.type = type.type + CTYPE_UCHAR - CTYPE_CHAR; + return type; } +/* --- Builder -------------------------------------------------------------- */ + CType ctype_tail(void) { return (CType){ @@ -15,6 +57,13 @@ CType ctype_tail(void) }; } +CType ctype_error(void) +{ + return (CType){ + .type = CTYPE_INVALID, + }; +} + CType ctype_void(void) { return (CType){ @@ -63,27 +112,87 @@ CType ctype_array(CType subtype, int size, Alloc *alloc) }; } -CType ctype_signed(int precision) +CType ctype_char(void) +{ + return (CType){ + .type = CTYPE_CHAR, + }; +} + +CType ctype_short(void) +{ + return (CType){ + .type = CTYPE_SHORT, + }; +} + +CType ctype_int(void) +{ + return (CType){ + .type = CTYPE_INT, + }; +} + +CType ctype_long(void) { return (CType){ - .type = CTYPE_SIGNED, - .signed_.precision = precision, + .type = CTYPE_LONG, }; } -CType ctype_unsigned(int precision) +CType ctype_longlong(void) { return (CType){ - .type = CTYPE_UNSIGNED, - .unsigned_.precision = precision, + .type = CTYPE_LONGLONG, }; } -CType ctype_float(int precision) +CType ctype_uchar(void) +{ + return (CType){ + .type = CTYPE_UCHAR, + }; +} + +CType ctype_ushort(void) +{ + return (CType){ + .type = CTYPE_USHORT, + }; +} + +CType ctype_uint(void) +{ + return (CType){ + .type = CTYPE_UINT, + }; +} + +CType ctype_ulong(void) +{ + return (CType){ + .type = CTYPE_ULONG, + }; +} + +CType ctype_ulonglong(void) +{ + return (CType){ + .type = CTYPE_ULONGLONG, + }; +} + +CType ctype_float(void) { return (CType){ .type = CTYPE_FLOAT, - .float_.precision = precision, + }; +} + +CType ctype_double(void) +{ + return (CType){ + .type = CTYPE_DOUBLE, }; } @@ -217,6 +326,6 @@ void ctype_append(CType *type, CType tail) break; default: - panic$("ctype_append on type {}", ctype_to_str(type->type)); + panic$("ctype_append on type {}", ctype_to_str(*type)); } } diff --git a/sources/libs/cc/builder/type.h b/sources/libs/cc/builder/type.h index c7a003d81..8d0f0b930 100644 --- a/sources/libs/cc/builder/type.h +++ b/sources/libs/cc/builder/type.h @@ -2,6 +2,12 @@ #include +Str ctype_to_str(CType type); + +CType ctype_to_unsigned(CType type); + +/* --- Builders ------------------------------------------------------------- */ + CType ctype_error(void); CType ctype_tail(void); @@ -18,11 +24,29 @@ CType ctype_parent(CType subtype, Alloc *alloc); CType ctype_array(CType subtype, int size, Alloc *alloc); -CType ctype_signed(int precision); +CType ctype_char(void); + +CType ctype_short(void); + +CType ctype_int(void); + +CType ctype_long(void); + +CType ctype_longlong(void); + +CType ctype_uchar(void); + +CType ctype_ushort(void); + +CType ctype_uint(void); + +CType ctype_ulong(void); + +CType ctype_ulonglong(void); -CType ctype_unsigned(int precision); +CType ctype_float(void); -CType ctype_float(int precision); +CType ctype_double(void); CType ctype_struct(Alloc *alloc); diff --git a/sources/libs/cc/builder/unit.c b/sources/libs/cc/builder/unit.c index 6ea914a7e..65fac9736 100644 --- a/sources/libs/cc/builder/unit.c +++ b/sources/libs/cc/builder/unit.c @@ -1,5 +1,31 @@ #include +bool cunit_contains_type(CUnit *context, Str name) +{ + vec_foreach_v(entry, &context->units) + { + if (entry.type == CUNIT_DECLARATION && entry._decl.type == CDECL_TYPE && str_eq(entry._decl.name, name)) + { + return true; + } + } + return false; +} + +bool cunit_contains_decl(CUnit *context, Str name) +{ + vec_foreach_v(entry, &context->units) + { + if (entry.type == CUNIT_DECLARATION && entry._decl.type != CDECL_TYPE && str_eq(entry._decl.name, name)) + { + return true; + } + } + return false; +} + +/* --- Builders ------------------------------------------------------------- */ + CUnit cunit(Alloc *alloc) { CUnit unit; diff --git a/sources/libs/cc/builder/unit.h b/sources/libs/cc/builder/unit.h index 8ce351f1b..a48e6e2d3 100644 --- a/sources/libs/cc/builder/unit.h +++ b/sources/libs/cc/builder/unit.h @@ -2,6 +2,12 @@ #include +bool cunit_contains_type(CUnit *context, Str name); + +bool cunit_contains_decl(CUnit *context, Str name); + +/* --- Builders ------------------------------------------------------------- */ + CUnit cunit(Alloc *alloc); void cunit_decl(CUnit *self, CDecl decl); diff --git a/sources/libs/cc/builder/val.c b/sources/libs/cc/builder/val.c index a5f8ea463..9e8b2685f 100644 --- a/sources/libs/cc/builder/val.c +++ b/sources/libs/cc/builder/val.c @@ -1,33 +1,183 @@ +#include +#include #include -CVal cval_signed(CSigned v) +static const char *cval_type_to_str_raw[CVAL_COUNT] = { + [CVAL_INVALID] = "invalid", + [CVAL_CHAR] = "char", + [CVAL_SHORT] = "short", + [CVAL_INT] = "int", + [CVAL_LONG] = "long", + [CVAL_LONGLONG] = "long long", + [CVAL_UCHAR] = "unsigned char", + [CVAL_USHORT] = "unsigned short", + [CVAL_UINT] = "unsigned int", + [CVAL_ULONG] = "unsigned long", + [CVAL_ULONGLONG] = "unsigned long long", + [CVAL_FLOAT] = "float", + [CVAL_DOUBLE] = "double", + [CVAL_STRING] = "string", +}; + +Str cval_to_str(CVal val) +{ + return str$(cval_type_to_str_raw[val.type]); +} + +CType cval_type(CVal value, Alloc *alloc) +{ + switch (value.type) + { + case CVAL_FLOAT: + return ctype_float(); + + case CVAL_CHAR: + return ctype_char(); + + case CVAL_SHORT: + return ctype_short(); + + case CVAL_INT: + return ctype_int(); + + case CVAL_LONG: + return ctype_long(); + + case CVAL_LONGLONG: + return ctype_longlong(); + + case CVAL_UCHAR: + return ctype_uchar(); + + case CVAL_USHORT: + return ctype_ushort(); + + case CVAL_UINT: + return ctype_uint(); + + case CVAL_ULONG: + return ctype_ulong(); + + case CVAL_ULONGLONG: + return ctype_ulonglong(); + + case CVAL_STRING: + return ctype_array(ctype_char(), value.str_.len, alloc); + + default: + panic$("invalid cval type"); + } +} + +/* --- Builder -------------------------------------------------------------- */ + +CVal cval_error(void) +{ + return (CVal){ + .type = CVAL_INVALID, + }; +} + +CVal cval_char(CSigned val) +{ + return (CVal){ + .type = CVAL_CHAR, + .signed_ = val, + }; +} + +CVal cval_short(CSigned val) +{ + return (CVal){ + .type = CVAL_SHORT, + .signed_ = val, + }; +} + +CVal cval_int(CSigned val) { return (CVal){ - .type = CVAL_SIGNED, - .signed_ = v, + .type = CVAL_INT, + .signed_ = val, }; } -CVal cval_unsigned(CUnsigned v) +CVal cval_long(CSigned val) { return (CVal){ - .type = CVAL_UNSIGNED, - .unsigned_ = v, + .type = CVAL_LONG, + .signed_ = val, }; } -CVal cval_float(double v) +CVal cval_longlong(CSigned val) +{ + return (CVal){ + .type = CVAL_LONGLONG, + .signed_ = val, + }; +} + +CVal cval_uchar(CUnsigned val) +{ + return (CVal){ + .type = CVAL_UCHAR, + .signed_ = val, + }; +} + +CVal cval_ushort(CUnsigned val) +{ + return (CVal){ + .type = CVAL_USHORT, + .signed_ = val, + }; +} + +CVal cval_uint(CUnsigned val) +{ + return (CVal){ + .type = CVAL_UINT, + .signed_ = val, + }; +} + +CVal cval_ulong(CUnsigned val) +{ + return (CVal){ + .type = CVAL_ULONG, + .signed_ = val, + }; +} + +CVal cval_ulonglong(CUnsigned val) +{ + return (CVal){ + .type = CVAL_ULONGLONG, + .signed_ = val, + }; +} + +CVal cval_float(double val) { return (CVal){ .type = CVAL_FLOAT, - .float_ = v, + .float_ = val, + }; +} + +CVal cval_double(double val) +{ + return (CVal){ + .type = CVAL_DOUBLE, + .float_ = val, }; } -CVal cval_string(Str str) +CVal cval_str(Str str) { return (CVal){ .type = CVAL_STRING, - .string_ = str, + .str_ = str, }; } diff --git a/sources/libs/cc/builder/val.h b/sources/libs/cc/builder/val.h index a884e2710..2bcbbeb12 100644 --- a/sources/libs/cc/builder/val.h +++ b/sources/libs/cc/builder/val.h @@ -1,28 +1,38 @@ #pragma once +#include #include -#define cval$(VAL) \ - _Generic((VAL), \ - signed int \ - : cval_signed, \ - signed long \ - : cval_signed, \ - signed char \ - : cval_signed, \ - signed short \ - : cval_signed, \ - unsigned int \ - : cval_unsigned, \ - unsigned long \ - : cval_unsigned, \ - float \ - : cval_float)(VAL) - -CVal cval_signed(CSigned v); - -CVal cval_unsigned(CUnsigned v); - -CVal cval_float(double v); - -CVal cval_string(Str str); +Str cval_to_str(CVal type); + +CType cval_type(CVal value, Alloc *alloc); + +/* --- Builders ------------------------------------------------------------- */ + +CVal cval_error(void); + +CVal cval_char(CSigned val); + +CVal cval_short(CSigned val); + +CVal cval_int(CSigned val); + +CVal cval_long(CSigned val); + +CVal cval_long_long(CSigned val); + +CVal cval_uchar(CUnsigned val); + +CVal cval_ushort(CUnsigned val); + +CVal cval_uint(CUnsigned val); + +CVal cval_ulong(CUnsigned val); + +CVal cval_ulonglong(CUnsigned val); + +CVal cval_float(double val); + +CVal cval_double(double val); + +CVal cval_str(Str str); diff --git a/sources/libs/cc/dump/dump.c b/sources/libs/cc/dump/dump.c index 10cec95e2..3e7b621e5 100644 --- a/sources/libs/cc/dump/dump.c +++ b/sources/libs/cc/dump/dump.c @@ -1,37 +1,63 @@ -#include -#include #include +#include +#include -Json cdump_value(CVal value, Alloc *alloc) +Json cval_to_json(CVal val) { - Json json = json_object(alloc); - json_put(&json, str$("type"), json_str(cval_type_to_str(value.type))); - - switch (value.type) - { - case CVAL_SIGNED: - { - json_put(&json, str$("value"), json_number(value.signed_)); - break; - } - case CVAL_UNSIGNED: + switch (val.type) { - json_put(&json, str$("value"), json_number(value.unsigned_)); - break; - } + case CVAL_INVALID: + return json_null(); + + case CVAL_CHAR: + return json_number((char)val.signed_); + + case CVAL_SHORT: + return json_number((short)val.signed_); + + case CVAL_INT: + return json_number((int)val.signed_); + + case CVAL_LONG: + return json_number((long)val.signed_); + + case CVAL_LONGLONG: + return json_number((long long)val.signed_); + + case CVAL_UCHAR: + return json_number((unsigned char)val.unsigned_); + + case CVAL_USHORT: + return json_number((unsigned short)val.unsigned_); + + case CVAL_UINT: + return json_number((unsigned int)val.unsigned_); + + case CVAL_ULONG: + return json_number((unsigned long)val.unsigned_); + + case CVAL_ULONGLONG: + return json_number((unsigned long long)val.unsigned_); + case CVAL_FLOAT: - { - json_put(&json, str$("value"), json_str(str$("float are not supported for the moment"))); - break; - } + return json_number((float)val.float_); + + case CVAL_DOUBLE: + return json_number((double)val.float_); + case CVAL_STRING: - { - json_put(&json, str$("value"), json_str(value.string_)); - break; - } + return json_str(val.str_); + default: - panic$("unknown value type {}", value.type); + panic$("invalid cval type"); } +} + +Json cdump_value(CVal value, Alloc *alloc) +{ + Json json = json_object_with_type(str$("CVal"), alloc); + json_put(&json, str$("type"), json_str(cval_to_str(value))); + json_put(&json, str$("value"), cval_to_json(value)); return json; } @@ -44,104 +70,56 @@ Json cdump_member(CTypeMembers const *members, Alloc *alloc) Json member_json = json_object(alloc); json_put(&member_json, str$("name"), json_str(member.name)); json_put(&member_json, str$("type"), cdump_type(member.type, alloc)); + json_append(&json, member_json); } return json; } Json cdump_type(CType type, Alloc *alloc) { + Json json = json_object_with_type(str$("CType"), alloc); + json_put(&json, str$("repr"), json_str(ctype_to_str(type))); + switch (type.type) { - case CTYPE_INVALID: - { - return json_str(str$("")); - } - case CTYPE_TAIL: - { - return json_str(str$("")); - } - case CTYPE_ERROR: - { - return json_str(str$("")); - } - case CTYPE_VOID: - { - return json_str(str$("void")); - } - case CTYPE_AUTO: - { - return json_str(str$("auto")); - } - case CTYPE_BOOL: - { - return json_str(str$("Bool")); - } case CTYPE_PTR: - { - Json json = json_object(alloc); - json_put(&json, str$("ptr"), cdump_type(*type.ptr_.subtype, alloc)); - return json; - } + json_put(&json, str$("subtype"), cdump_type(*type.ptr_.subtype, alloc)); + break; + case CTYPE_PARENT: - { - Json json = json_object(alloc); - json_put(&json, str$("parent"), cdump_type(*type.parent_.subtype, alloc)); - return json; - } + json_put(&json, str$("subtype"), cdump_type(*type.parent_.subtype, alloc)); + break; + case CTYPE_ARRAY: - { - Json json = json_object(alloc); - json_put(&json, str$("array"), cdump_type(*type.array_.subtype, alloc)); + json_put(&json, str$("subtype"), cdump_type(*type.array_.subtype, alloc)); if (type.array_.size != CTYPE_ARRAY_UNBOUNDED) { json_put(&json, str$("size"), json_number(type.array_.size)); } - return json; - } - case CTYPE_SIGNED: - { - return json_str(str$("signed")); - } - case CTYPE_UNSIGNED: - { - return json_str(str$("unsigned")); - } - case CTYPE_FLOAT: - { - return json_str(str$("float")); - } + break; + case CTYPE_STRUCT: - { - Json json = json_object(alloc); - json_put(&json, str$("struct"), cdump_member(&type.struct_.members, alloc)); - return json; - } + json_put(&json, str$("members"), cdump_member(&type.struct_.members, alloc)); + break; + case CTYPE_UNION: - { - Json json = json_object(alloc); - json_put(&json, str$("union"), cdump_member(&type.struct_.members, alloc)); - return json; - } - case CTYPE_ENUM: - { - return json_str(str$("enum")); - } + json_put(&json, str$("members"), cdump_member(&type.struct_.members, alloc)); + break; + case CTYPE_FUNC: - { - Json json = json_object(alloc); - json_put(&json, str$("func"), cdump_type(*type.func_.ret, alloc)); + json_put(&json, str$("ret"), cdump_type(*type.func_.ret, alloc)); json_put(&json, str$("args"), cdump_member(&type.func_.params, alloc)); - return json; - } + break; + case CTYPE_NAME: - { - Json json = json_object(alloc); json_put(&json, str$("name"), json_str(type.name)); - return json; - } + break; + default: - panic$("unknown ctype type {}", type.type); + break; } + + return json; } Json cdump_expr(CExpr expr, Alloc *alloc) @@ -247,7 +225,7 @@ Json cdump_stmt(CStmt stmt, Alloc *alloc) case CSTMT_DEFAULT: case CSTMT_BREAK: { - return json_str(cstmt_type_to_str(stmt.type)); + return json_str(cstmt_to_str(stmt.type)); } case CSTMT_DECL: { @@ -339,6 +317,7 @@ Json cdump_stmt(CStmt stmt, Alloc *alloc) Json cdump_decl(CDecl decl, Alloc *alloc) { Json json = json_object(alloc); + if (decl.sema_type.type != CTYPE_INVALID) { json_put(&json, str$("sema-type"), cdump_type(decl.sema_type, alloc)); @@ -363,7 +342,7 @@ Json cdump_decl(CDecl decl, Alloc *alloc) } else if (decl.type == CDECL_EMPTY) { - json_put(&json, str$("empty"), json_str(str$("empty"))); + json_put(&json, str$("nil"), json_str(str$("nil"))); } else { @@ -375,12 +354,13 @@ Json cdump_decl(CDecl decl, Alloc *alloc) Json cdump_unit(CUnit unit, Alloc *alloc) { Json json = json_object(alloc); - /* todo: add file info and more here */ Json units = json_array(alloc); + vec_foreach_v(entry, &unit.units) { switch (entry.type) { + case CUNIT_INCLUDE: { Json include = json_object(alloc); @@ -389,6 +369,7 @@ Json cdump_unit(CUnit unit, Alloc *alloc) json_append(&units, include); break; } + case CUNIT_PRAGMA: { Json pragma = json_object(alloc); @@ -396,11 +377,13 @@ Json cdump_unit(CUnit unit, Alloc *alloc) json_append(&units, pragma); break; } + case CUNIT_DECLARATION: { json_append(&units, cdump_decl(entry._decl, alloc)); break; } + case CUNIT_DEFINE: { Json def = json_object(alloc); diff --git a/sources/libs/cc/lex/lexemes.h b/sources/libs/cc/lex/lexemes.h index a10bd01e5..a4e250b48 100644 --- a/sources/libs/cc/lex/lexemes.h +++ b/sources/libs/cc/lex/lexemes.h @@ -6,7 +6,7 @@ LEXEME(COMMENT) \ LEXEME(NEWLINE) \ LEXEME(IDENT) \ - LEXEME(INTEGER) \ + LEXEME(NUMBER) \ LEXEME(AUTO) \ LEXEME(BREAK) \ LEXEME(CASE) \ diff --git a/sources/libs/cc/lex/lexer.c b/sources/libs/cc/lex/lexer.c index dc406abfb..2dbf6da84 100644 --- a/sources/libs/cc/lex/lexer.c +++ b/sources/libs/cc/lex/lexer.c @@ -99,6 +99,55 @@ static int isidentchar(char v) return isalpha(v) || v == '_' || v == '$' || isdigit(v); } +static bool skip_bin_literal(Scan *scan) +{ + if (scan_skip_word(scan, str$("0b")) || scan_skip_word(scan, str$("0B"))) + { + while (scan_skip_any(scan, str$("01"))) + ; + return true; + } + + return false; +} + +static bool skip_octal_literal(Scan *scan) +{ + if (scan_skip_word(scan, str$("0"))) + { + while (scan_skip_any(scan, str$("01234567"))) + ; + return true; + } + + return false; +} + +static bool skip_dec_literal(Scan *scan) +{ + while (scan_skip_any(scan, str$("0123456789"))) + ; + return true; +} + +static bool skip_hex_literal(Scan *scan) +{ + if (scan_skip_word(scan, str$("0x")) || scan_skip_word(scan, str$("0X"))) + { + while (scan_skip_any_nc(scan, str$("0123456789abcdef"))) + ; + return true; + } + + return false; +} + +static void skip_int_suffix(Scan *scan) +{ + while (scan_skip_any_nc(scan, str$("ul"))) + ; +} + static LexemeType clex_impl(Scan *scan) { @@ -129,7 +178,11 @@ static LexemeType clex_impl(Scan *scan) return (CLEX_COMMENT); } - else if (scan_skip_word(scan, str$("\""))) + else if (scan_skip_word(scan, str$("\"")) || + scan_skip_word(scan, str$("u8\"")) || + scan_skip_word(scan, str$("u\"")) || + scan_skip_word(scan, str$("U\"")) || + scan_skip_word(scan, str$("L\""))) { while (!scan_skip(scan, '"') && !scan_ended(scan)) @@ -141,7 +194,7 @@ static LexemeType clex_impl(Scan *scan) } else if (scan_skip_word(scan, str$("'"))) { - if (scan_curr(scan) != '\'') // case for just '' + if (scan_curr(scan) != '\'') { scan_next(scan); } @@ -158,14 +211,13 @@ static LexemeType clex_impl(Scan *scan) } } - if (isdigit(scan_curr(scan))) + if (skip_bin_literal(scan) || + skip_octal_literal(scan) || + skip_dec_literal(scan) || + skip_hex_literal(scan)) { - while (isdigit(scan_curr(scan)) && !scan_ended(scan)) - { - scan_next(scan); - } - - return CLEX_INTEGER; + skip_int_suffix(scan); + return CLEX_NUMBER; } if (isidentchar(scan_curr(scan))) @@ -181,7 +233,7 @@ static LexemeType clex_impl(Scan *scan) return (LEXEME_INVALID); } -Lex clex(Scan *scan, Alloc *alloc) +Lex clex(Scan *scan, Alloc *alloc, int tu) { - return lex(scan, clex_impl, alloc); + return lex_tu(scan, clex_impl, alloc, tu); } diff --git a/sources/libs/cc/lex/lexer.h b/sources/libs/cc/lex/lexer.h index 1b073688e..3648fa60f 100644 --- a/sources/libs/cc/lex/lexer.h +++ b/sources/libs/cc/lex/lexer.h @@ -32,4 +32,4 @@ static inline Str clex_to_str(LexemeType type) return lexeme_to_str(type); } -Lex clex(Scan *scan, Alloc *alloc); +Lex clex(Scan *scan, Alloc *alloc, int tu); diff --git a/sources/libs/cc/lex/pproc.c b/sources/libs/cc/lex/pproc.c index 4a9553076..e00357511 100644 --- a/sources/libs/cc/lex/pproc.c +++ b/sources/libs/cc/lex/pproc.c @@ -27,7 +27,7 @@ CProcMacro *cproc_define(CProc *ctx, Str name, Str value) Scan scan = {}; scan_init(&scan, value); - Lex source = clex(&scan, ctx->alloc); + Lex source = clex(&scan, ctx->alloc, 0); cproc_macro_code(¯o, &source); @@ -224,7 +224,7 @@ static void cproc_gen_concatenation(Lex *out, Lex *macro_source, CProc *ctx) Scan scanner; scan_init(&scanner, final.str); - Lex concatenated = clex(&scanner, ctx->alloc); + Lex concatenated = clex(&scanner, ctx->alloc, 0); log$(final.str); if (concatenated.lexemes.len > 1) { diff --git a/sources/libs/cc/parse/cval.c b/sources/libs/cc/parse/cval.c index 1c4ac1982..f1b6b4f8d 100644 --- a/sources/libs/cc/parse/cval.c +++ b/sources/libs/cc/parse/cval.c @@ -4,46 +4,64 @@ static CVal cparse_cval_char(Lex *lex) { Str from_str = lex_curr(lex).str; - Str final_string = str_sub(from_str, 1, from_str.len - 1); + Str final_str = str_sub(from_str, 1, from_str.len - 1); lex_skip_type(lex, CLEX_CHARACTER); - return cval_string(final_string); + return cval_str(final_str); } -static CVal cparse_cval_string(Lex *lex) +static CVal cparse_cval_str(Lex *lex) { + Str from_str = lex_curr(lex).str; - Str final_string = str_sub(from_str, 1, from_str.len - 1); + Str final_str = str_sub(from_str, 1, from_str.len - 1); lex_skip_type(lex, CLEX_STRING); - return cval_string(final_string); + return cval_str(final_str); } static CVal cparse_cval_integer(Lex *lex) { long value = 0; + str_to_int(lex_curr(lex).str, &value); - lex_skip_type(lex, CLEX_INTEGER); + lex_skip_type(lex, CLEX_NUMBER); + + return cval_int(value); +} + +static CVal cparse_cval_float(Lex *lex) +{ + double value = 0; + + str_to_float(lex_curr(lex).str, &value); + lex_skip_type(lex, CLEX_NUMBER); - return cval_signed(value); + return cval_float(value); } CVal cparse_val(Lex *lex) { + CVal result = cval_error(); + + int begin = lex->head; + if (lex_curr_type(lex) == CLEX_STRING) { - return cparse_cval_string(lex); + result = cparse_cval_str(lex); } - - if (lex_curr_type(lex) == CLEX_CHARACTER) + else if (lex_curr_type(lex) == CLEX_CHARACTER) { - return cparse_cval_char(lex); + result = cparse_cval_char(lex); } - - if (lex_curr_type(lex) == CLEX_INTEGER) + else if (lex_curr_type(lex) == CLEX_NUMBER) + { + result = cparse_cval_integer(lex); + } + else if (lex_curr_type(lex) == CLEX_NUMBER) { - return cparse_cval_integer(lex); + result = cparse_cval_float(lex); } - return (CVal){.type = CVAL_INVALID}; + return with_cref$(result, begin, lex); } diff --git a/sources/libs/cc/parse/decl.c b/sources/libs/cc/parse/decl.c index a5c20b038..248eb9b55 100644 --- a/sources/libs/cc/parse/decl.c +++ b/sources/libs/cc/parse/decl.c @@ -17,8 +17,10 @@ void cparse_func_params(Lex *lex, CType *type, Alloc *alloc) CType cparse_declarator_postfix(Lex *lex, CType type, Alloc *alloc) { + int begin = lex->head; if (cparse_skip_separator(lex, CLEX_LPARENT)) { + CType func = ctype_func(ctype_tail(), alloc); cparse_func_params(lex, &func, alloc); @@ -26,7 +28,7 @@ CType cparse_declarator_postfix(Lex *lex, CType type, Alloc *alloc) CType ret = cparse_declarator_postfix(lex, type, alloc); ctype_append(&func, ret); - return func; + return with_cref$(func, begin, lex); } else if (cparse_skip_separator(lex, CLEX_LBRACKET)) { @@ -34,7 +36,7 @@ CType cparse_declarator_postfix(Lex *lex, CType type, Alloc *alloc) long size = CTYPE_ARRAY_UNBOUNDED; - if (lex_curr_type(lex) == CLEX_INTEGER) + if (lex_curr_type(lex) == CLEX_NUMBER) { str_to_int(lex_next(lex).str, &size); } @@ -43,7 +45,7 @@ CType cparse_declarator_postfix(Lex *lex, CType type, Alloc *alloc) CType inner = cparse_declarator_postfix(lex, type, alloc); - return ctype_array(inner, size, alloc); + return with_cref$(ctype_array(inner, size, alloc), begin, lex); } else { @@ -96,11 +98,13 @@ CDeclarator cparse_declarator_prefix(Lex *lex, CType type, Alloc *alloc) CDeclarator cparse_declarator(Lex *lex, Alloc *alloc) { + int begin = lex->head; CType type = cparse_type(lex, alloc); cparse_whitespace(lex); CDeclarator decl = cparse_declarator_prefix(lex, type, alloc); decl.type = cparse_declarator_postfix(lex, decl.type, alloc); + decl.type = with_cref$(decl.type, begin, lex); return decl; } @@ -151,17 +155,18 @@ CDeclAttr cparse_decl_attr(Lex *lex) CDecl cparse_decl(Lex *lex, CUnit *context, Alloc *alloc) { + int begin = lex->head; if (cparse_is_separator(lex, CLEX_SEMICOLON)) { cparse_skip_separator(lex, CLEX_SEMICOLON); - return cdecl_empty(); + return with_cref$(cdecl_empty(), begin, lex); } else if (lex_skip_type(lex, CLEX_TYPEDEF)) { cparse_whitespace(lex); CDeclarator declarator = cparse_declarator(lex, alloc); - return cdecl_type(declarator.name, declarator.type); + return with_cref$(cdecl_type(declarator.name, declarator.type), begin, lex); } else { @@ -174,12 +179,12 @@ CDecl cparse_decl(Lex *lex, CUnit *context, Alloc *alloc) if (cparse_is_separator(lex, CLEX_LBRACE)) { CStmt body = cparse_stmt(lex, context, alloc); - return cdecl_attrib(cdecl_func(decl.name, decl.type, body), attr); + return with_cref$(cdecl_attrib(cdecl_func(decl.name, decl.type, body), attr), begin, lex); } else { cparse_expect_separator(lex, CLEX_SEMICOLON); - return cdecl_attrib(cdecl_func(decl.name, decl.type, cstmt_empty()), attr); + return with_cref$(cdecl_attrib(cdecl_func(decl.name, decl.type, cstmt_empty()), attr), begin, lex); } } else @@ -187,12 +192,12 @@ CDecl cparse_decl(Lex *lex, CUnit *context, Alloc *alloc) if (cparse_skip_separator(lex, CLEX_EQUAL)) { CExpr init = cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc); - return cdecl_var(decl.name, decl.type, init); + return with_cref$(cdecl_var(decl.name, decl.type, init), begin, lex); } else { cparse_expect_separator(lex, CLEX_SEMICOLON); - return cdecl_attrib(cdecl_var(decl.name, decl.type, cexpr_empty()), attr); + return with_cref$(cdecl_attrib(cdecl_var(decl.name, decl.type, cexpr_empty()), attr), begin, lex); } } } diff --git a/sources/libs/cc/parse/expr.c b/sources/libs/cc/parse/expr.c index 166f4707a..a90dd7ebf 100644 --- a/sources/libs/cc/parse/expr.c +++ b/sources/libs/cc/parse/expr.c @@ -1,7 +1,7 @@ -#include -#include #include #include +#include +#include static COp lexeme_to_cop[CLEX_COUNT] = { [CLEX_PLUSPLUS] = COP_INC, @@ -50,7 +50,7 @@ COp cparse_lexeme_to_cop(LexemeType type) static CExpr cparse_parent_expr(Lex *lex, CUnit *context, Alloc *alloc) { CExpr result; - + int begin = lex->head; cparse_whitespace(lex); if (lex_curr_type(lex) == CLEX_IDENT && cunit_contains_type(context, lex_curr(lex).str)) { @@ -65,28 +65,31 @@ static CExpr cparse_parent_expr(Lex *lex, CUnit *context, Alloc *alloc) cparse_skip_separator(lex, CLEX_RPARENT); } - return result; + return with_cref$(result, begin, lex); } + static CExpr cparse_primary_expr(Lex *lex, CUnit *context, Alloc *alloc) { + int begin = lex->head; if (cparse_is_separator(lex, CLEX_IDENT)) { Str val = lex_curr(lex).str; cparse_skip_separator(lex, CLEX_IDENT); - return cexpr_ident(val); + return with_cref$(cexpr_ident(val), begin, lex); } - - else if (cparse_is_separator(lex, CLEX_INTEGER)) + else if (cparse_is_separator(lex, CLEX_NUMBER)) { - return cexpr_constant(cparse_val(lex)); + return with_cref$(cexpr_constant(cparse_val(lex)), begin, lex); + } + else if (cparse_is_separator(lex, CLEX_STRING)) + { + return with_cref$(cexpr_constant(cparse_val(lex)), begin, lex); } - else if (cparse_skip_separator(lex, CLEX_LPARENT)) { CExpr expr = cparse_parent_expr(lex, context, alloc); - return expr; + return with_cref$(expr, begin, lex); } - else if (cparse_skip_separator(lex, CLEX_LBRACKET)) { // TODO: parse lambda capture @@ -100,14 +103,14 @@ static CExpr cparse_primary_expr(Lex *lex, CUnit *context, Alloc *alloc) CStmt body = cparse_stmt(lex, context, alloc); - return cexpr_lambda(type, body, alloc); + return with_cref$(cexpr_lambda(type, body, alloc), begin, lex); } else { lex_throw(lex, str$("Unexpect token!")); - return cexpr_empty(); + return with_cref$(cexpr_empty(), begin, lex); } - return cexpr_constant(cval$(0)); + return with_cref$(cexpr_constant(cval_uint(0)), begin, lex); } static void cparse_func_call_args(Lex *lex, CExpr *target, CUnit *context, Alloc *alloc) @@ -126,7 +129,7 @@ static void cparse_func_call_args(Lex *lex, CExpr *target, CUnit *context, Alloc } static void cparse_postfix_expr(Lex *lex, CExpr *target, CUnit *context, Alloc *alloc) { - + int begin = lex->head; if (cparse_skip_separator(lex, CLEX_LPARENT)) { *target = cexpr_call(alloc, *target); @@ -146,11 +149,13 @@ static void cparse_postfix_expr(Lex *lex, CExpr *target, CUnit *context, Alloc * { *target = cexpr_postdec(*target, alloc); } + *target = with_cref$(*target, begin, lex); } + static CExpr cparse_prefix_expr(Lex *lex, CUnit *context, Alloc *alloc) { CExpr result; - + int begin = lex->head; // FIXME: put every parse prefix if (cparse_skip_separator(lex, CLEX_MINUS)) { @@ -169,7 +174,7 @@ static CExpr cparse_prefix_expr(Lex *lex, CUnit *context, Alloc *alloc) cparse_postfix_expr(lex, &result, context, alloc); } - return result; + return with_cref$(result, begin, lex); } bool cparse_is_end_expr(LexemeType type) @@ -179,6 +184,7 @@ bool cparse_is_end_expr(LexemeType type) CExpr cparse_expr(Lex *lex, int pre, CUnit *context, Alloc *alloc) { + int begin = lex->head; CExpr left = cparse_prefix_expr(lex, context, alloc); CExpr right; @@ -187,7 +193,7 @@ CExpr cparse_expr(Lex *lex, int pre, CUnit *context, Alloc *alloc) if (cparse_is_end_expr(curr_lex.type)) { - return left; + return with_cref$(left, begin, lex); } while (!lex_ended(lex) && cop_pre(cparse_lexeme_to_cop(curr_lex.type)) < pre) @@ -205,12 +211,8 @@ CExpr cparse_expr(Lex *lex, int pre, CUnit *context, Alloc *alloc) if (cparse_is_end_expr(curr_lex.type)) { - return left; + return with_cref$(left, begin, lex); } } - return left; -} - -/* + return with_cref$(left, begin, lex); } -*/ diff --git a/sources/libs/cc/parse/misc.c b/sources/libs/cc/parse/misc.c index c888488f7..442447619 100644 --- a/sources/libs/cc/parse/misc.c +++ b/sources/libs/cc/parse/misc.c @@ -33,7 +33,8 @@ bool cparse_is_separator(Lex *lex, LexemeType type) Lexeme cparse_peek_separator(Lex *lex, int offset) { int off = 0; - while (lex_peek_type(lex, off) == CLEX_WHITESPACE && off != offset && !lex_ended(lex)) + while (lex_peek_type(lex, off) == CLEX_WHITESPACE && + off != offset && !lex_ended(lex)) { off++; } diff --git a/sources/libs/cc/parse/parser.h b/sources/libs/cc/parse/parser.h index 3195a1749..3ac991c44 100644 --- a/sources/libs/cc/parse/parser.h +++ b/sources/libs/cc/parse/parser.h @@ -30,3 +30,5 @@ bool cparse_skip_separator(Lex *lex, LexemeType type); bool cparse_is_separator(Lex *lex, LexemeType type); Lexeme cparse_peek_separator(Lex *lex, int offset); + +bool is_cparse_type(Lex *lex, CUnit *context); diff --git a/sources/libs/cc/parse/stmt.c b/sources/libs/cc/parse/stmt.c index 646e52dba..6e6a8e9c5 100644 --- a/sources/libs/cc/parse/stmt.c +++ b/sources/libs/cc/parse/stmt.c @@ -3,6 +3,7 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) { + int begin = lex->head; if (cparse_skip_separator(lex, CLEX_LBRACE)) { CStmt block = cstmt_block(alloc); @@ -14,7 +15,7 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) cparse_skip_separator(lex, CLEX_SEMICOLON); } - return block; + return with_cref$(block, begin, lex); } else if (cparse_skip_separator(lex, CLEX_IF)) { @@ -31,7 +32,7 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) CStmt stmt_false = cparse_stmt(lex, context, alloc); - return cstmt_if_else(expr, stmt_true, stmt_false, alloc); + return with_cref$(cstmt_if_else(expr, stmt_true, stmt_false, alloc), begin, lex); } else if (cparse_skip_separator(lex, CLEX_FOR)) { @@ -51,7 +52,7 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) CStmt stmt = cparse_stmt(lex, context, alloc); - return cstmt_for(init_stmt, cond_expr, iter_expr, stmt, alloc); + return with_cref$(cstmt_for(init_stmt, cond_expr, iter_expr, stmt, alloc), begin, lex); } else if (cparse_skip_separator(lex, CLEX_WHILE)) { @@ -63,7 +64,7 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) CStmt stmt = cparse_stmt(lex, context, alloc); - return cstmt_while(expr, stmt, alloc); + return with_cref$(cstmt_while(expr, stmt, alloc), begin, lex); } else if (cparse_skip_separator(lex, CLEX_DO)) { @@ -77,7 +78,7 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) cparse_expect_separator(lex, CLEX_RPARENT); - return cstmt_do(expr, stmt, alloc); + return with_cref$(cstmt_do(expr, stmt, alloc), begin, lex); } else if (cparse_skip_separator(lex, CLEX_SWITCH)) { @@ -89,12 +90,12 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) CStmt stmt = cparse_stmt(lex, context, alloc); - return cstmt_switch(expr, stmt, alloc); + return with_cref$(cstmt_switch(expr, stmt, alloc), begin, lex); } else if (cparse_skip_separator(lex, CLEX_RETURN)) { CExpr expr = cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc); - return cstmt_return(expr); + return with_cref$(cstmt_return(expr), begin, lex); } else if (cparse_skip_separator(lex, CLEX_GOTO)) { @@ -102,33 +103,30 @@ CStmt cparse_stmt(Lex *lex, CUnit *context, Alloc *alloc) { Str label = lex_curr(lex).str; lex_next(lex); - return cstmt_goto(label); + return with_cref$(cstmt_goto(label), begin, lex); } else { lex_expect(lex, CLEX_IDENT); - return cstmt_empty(); + return with_cref$(cstmt_empty(), begin, lex); } } else if (cparse_skip_separator(lex, CLEX_CASE)) { CExpr expr = cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc); - return cstmt_case(expr); + return with_cref$(cstmt_case(expr), begin, lex); } - else if (cparse_is_separator(lex, CLEX_IDENT)) + else if (cunit_contains_decl(context, lex_curr(lex).str)) { - Str ident = lex_curr(lex).str; - if (cunit_contains_type(context, ident)) - { - return cstmt_decl(cparse_decl(lex, context, alloc), alloc); - } - else - { - return cstmt_expr(cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc)); - } + return with_cref$(cstmt_expr(cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc)), begin, lex); + } + else if (is_cparse_type(lex, context)) + { + return with_cref$(cstmt_decl(cparse_decl(lex, context, alloc), alloc), begin, lex); } + else { - return cstmt_expr(cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc)); + return with_cref$(cstmt_expr(cparse_expr(lex, CEXPR_MAX_PRECEDENCE, context, alloc)), begin, lex); } } diff --git a/sources/libs/cc/parse/type.c b/sources/libs/cc/parse/type.c index 5e8e63882..e43c72d9e 100644 --- a/sources/libs/cc/parse/type.c +++ b/sources/libs/cc/parse/type.c @@ -1,6 +1,6 @@ #include -CType cparse_compound_type(Lex *lex, bool is_union, Alloc *alloc) +static CType cparse_compound_type(Lex *lex, bool is_union, Alloc *alloc) { CType compound; @@ -43,63 +43,149 @@ CType cparse_compound_type(Lex *lex, bool is_union, Alloc *alloc) return compound; } -CType cparse_type(Lex *lex, Alloc *alloc) +CType cparse_enum_type(Lex *lex, Alloc *alloc) { - if (lex_skip_type(lex, CLEX_STRUCT)) + CType result = ctype_enum(alloc); + + cparse_whitespace(lex); + + if (lex_curr(lex).type == CLEX_IDENT) { - return cparse_compound_type(lex, false, alloc); + Str name = lex_next(lex).str; + ctype_named(result, name); + cparse_whitespace(lex); } - else if (lex_skip_type(lex, CLEX_UNION)) + + if (!lex_skip_type(lex, CLEX_LBRACE)) { - return cparse_compound_type(lex, true, alloc); + return result; } - else if (lex_skip_type(lex, CLEX_ENUM)) - { - CType enum_type = ctype_enum(alloc); + cparse_whitespace(lex); + + while (!lex_ended(lex) && lex_skip_type(lex, CLEX_SEMICOLON)) + { cparse_whitespace(lex); + } - if (lex_curr(lex).type == CLEX_IDENT) - { - Str name = lex_next(lex).str; - ctype_named(enum_type, name); - cparse_whitespace(lex); - } + cparse_whitespace(lex); - if (!lex_skip_type(lex, CLEX_LBRACE)) - { - return enum_type; - } + lex_expect(lex, CLEX_RBRACE); - cparse_whitespace(lex); + return result; +} - while (!lex_ended(lex) && lex_skip_type(lex, CLEX_SEMICOLON)) +CType cparse_signed_type(Lex *lex) +{ + if (lex_skip_type(lex, CLEX_CHAR)) + { + return ctype_char(); + } + else if (lex_skip_type(lex, CLEX_SHORT)) + { + return ctype_char(); + } + else if (lex_skip_type(lex, CLEX_INT)) + { + return ctype_int(); + } + else if (lex_skip_type(lex, CLEX_LONG)) + { + if (lex_skip_type(lex, CLEX_LONG)) { - cparse_whitespace(lex); + return ctype_longlong(); } + else + { + return ctype_long(); + } + } + else + { + lex_throw(lex, str$("Unexpected token")); + return ctype_error(); + } +} - cparse_whitespace(lex); - - lex_expect(lex, CLEX_RBRACE); +CType cparse_type(Lex *lex, Alloc *alloc) +{ + int begin = lex->head; + CType result = ctype_error(); - return enum_type; + if (lex_skip_type(lex, CLEX_STRUCT)) + { + result = cparse_compound_type(lex, false, alloc); + } + else if (lex_skip_type(lex, CLEX_UNION)) + { + result = cparse_compound_type(lex, true, alloc); + } + else if (lex_skip_type(lex, CLEX_ENUM)) + { + result = cparse_enum_type(lex, alloc); + } + else if (lex_curr_type(lex) == CLEX_IDENT) + { + result = ctype_ident(lex_next(lex).str); } else if (lex_skip_type(lex, CLEX_VOID)) { - return ctype_void(); + result = ctype_void(); } else if (lex_skip_type(lex, CLEX_BOOL)) { - return ctype_bool(); + result = ctype_bool(); } - else if (lex_curr_type(lex) == CLEX_IDENT) + else if (lex_skip_type(lex, CLEX_SIGNED)) { - Str name = lex_next(lex).str; - return ctype_ident(name); + result = cparse_signed_type(lex); + } + else if (lex_skip_type(lex, CLEX_UNSIGNED)) + { + result = ctype_to_unsigned(cparse_signed_type(lex)); + } + else if (lex_skip_type(lex, CLEX_FLOAT)) + { + result = ctype_float(); + } + else if (lex_skip_type(lex, CLEX_DOUBLE)) + { + result = ctype_double(); } else { - lex_throw(lex, str$("Unexpected token")); - return ctype_error(); + result = cparse_signed_type(lex); + } + + return with_cref$(result, begin, lex); +} + +bool is_cparse_type(Lex *lex, CUnit *context) +{ + switch (lex_curr_type(lex)) + { + case CLEX_STRUCT: + case CLEX_UNION: + case CLEX_ENUM: + case CLEX_VOID: + case CLEX_BOOL: + + case CLEX_CHAR: + case CLEX_SHORT: + case CLEX_INT: + case CLEX_LONG: + + case CLEX_UNSIGNED: + case CLEX_SIGNED: + + case CLEX_FLOAT: + case CLEX_DOUBLE: + return true; + + case CLEX_IDENT: + return cunit_contains_type(context, lex_curr(lex).str); + + default: + return false; } } diff --git a/sources/libs/cc/sema.h b/sources/libs/cc/sema.h index ea9789e40..b19dc6428 100644 --- a/sources/libs/cc/sema.h +++ b/sources/libs/cc/sema.h @@ -1,5 +1,5 @@ #pragma once - +#include #include #include #include diff --git a/sources/libs/cc/sema/cast.c b/sources/libs/cc/sema/cast.c deleted file mode 100644 index bc97dc7fd..000000000 --- a/sources/libs/cc/sema/cast.c +++ /dev/null @@ -1,2 +0,0 @@ - -#include diff --git a/sources/libs/cc/sema/cast.h b/sources/libs/cc/sema/cast.h deleted file mode 100644 index 119070cbb..000000000 --- a/sources/libs/cc/sema/cast.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -bool can_be_casted(bool explicit, CType to, CType from); diff --git a/sources/libs/cc/sema/passes.c b/sources/libs/cc/sema/passes.c new file mode 100644 index 000000000..a086d57ac --- /dev/null +++ b/sources/libs/cc/sema/passes.c @@ -0,0 +1,133 @@ +#include +#include +#include + +void cpass_scope_propagation(CSema *ctx, int what, void *node) +{ + bool is_scope = + cvisit_node_is(node, CVISIT_DECL, CDECL_FUNC) && + cvisit_node_is(node, CVISIT_STMT, CSTMT_BLOCK) && + cvisit_node_is(node, CVISIT_UNIT, 0); + + if (!is_scope) + return; + + if (what & CVISIT_BEGIN) + { + if (cvisit_node_is(node, CVISIT_DECL, CDECL_FUNC)) + { + csema_scope_enter_func(ctx, ((CDecl *)node)->func_.type); + } + else + { + csema_scope_enter(ctx); + } + } + else + { + csema_scope_leave(ctx); + } +} + +void cpass_types_propagation(MAYBE_UNUSED CSema *ctx, MAYBE_UNUSED int what, MAYBE_UNUSED void *node) +{ + + if (what & CVISIT_BEGIN) + { + } + else + { + } +} + +void cpass_op_array(CSema *ctx, int, void *node) +{ + CExpr *expr = node; + + if (expr->type != CEXPR_INFIX || expr->infix_.op != COP_INDEX) + { + return; + } + + CType lhs = expr->infix_.lhs->sema_type; + + if (lhs.type != CTYPE_ARRAY && lhs.type != CTYPE_PTR) + { + int id = csema_report$(ctx, PARSE_ERR, *expr, "Trying to use an array operator with a non ptr/array object"); + + Str str = ctrans_type_str(*expr->infix_.lhs, ctx->alloc); + csema_comment$(ctx, id, *expr->infix_.lhs, "Expression with type: {}", str); + } +} + +void cpass_op_deref(CSema *ctx, int, void *node) +{ + CExpr *expr = node; + + if (expr->type != CEXPR_PREFIX || expr->prefix_.op != COP_DEREF) + { + return; + } + + CType left_type = expr->prefix_.expr->sema_type; + + if (left_type.type != CTYPE_ARRAY && left_type.type != CTYPE_PTR) + { + int id = csema_report$(ctx, PARSE_ERR, *expr, "Trying to use an deref operator with a non ptr/array object"); + + Str str = ctrans_type_str(*expr->prefix_.expr, ctx->alloc); + csema_comment$(ctx, id, *expr->prefix_.expr, "Expression with type: {}", str); + } +} + +void cpass_expr_call(CSema *ctx, int, void *node) +{ + CExpr *expr = node; + + if (expr->type != CEXPR_CALL) + { + return; + } + + CType left_type = expr->call_.expr->sema_type; + + if (left_type.type != CTYPE_FUNC) + { + int id = csema_report$(ctx, PARSE_ERR, *expr, "calling a non callable expression"); + + Str str = ctrans_type_str(*expr->call_.expr, ctx->alloc); + csema_comment$(ctx, id, *expr->call_.expr, "Expression with type: {}", str); + } +} + +void cpass_decl_def(CSema *ctx, int, void *node) +{ + CDecl *decl = node; + + CDecl other; + if (csema_lookup_current_scope(ctx, decl->name, &other)) + { + int id = csema_report$(ctx, PARSE_ERR, *decl, "redefinition of: {}", decl->name); + csema_comment$(ctx, id, other, "already defined here"); + } +} + +void cpass_decl_deref(CSema *ctx, int, void *node) +{ + CExpr *expr = node; + + CDecl prev; + if (expr->type == CEXPR_IDENT && !csema_lookup(ctx, expr->ident_, &prev)) + { + csema_report$(ctx, PARSE_ERR, *expr, "Not defined symbol: {}", expr->ident_); + } +} + +static CVisit passes[] = { + {}, +}; + +CVisites cpass_all(void) +{ + return slice_array$(CVisites, passes); +} diff --git a/sources/libs/cc/sema/passes.h b/sources/libs/cc/sema/passes.h new file mode 100644 index 000000000..34856ace8 --- /dev/null +++ b/sources/libs/cc/sema/passes.h @@ -0,0 +1,3 @@ +#pragma once + +#include diff --git a/sources/libs/cc/sema/scope.c b/sources/libs/cc/sema/scope.c index b70b99a4b..1f0a2737f 100644 --- a/sources/libs/cc/sema/scope.c +++ b/sources/libs/cc/sema/scope.c @@ -3,7 +3,7 @@ void cscope_init(CScope *self, Alloc *alloc) { *self = (CScope){}; - self->expected_result.type = CTYPE_INVALID; + self->ret.type = CTYPE_INVALID; vec_init(&self->decls, alloc); } @@ -12,17 +12,18 @@ void cscope_deinit(CScope *self) vec_deinit(&self->decls); } -CDecl cscope_lookup(CScope *self, Str name) +bool cscope_lookup(CScope *self, Str name, CDecl *out_decl) { - - vec_foreach(decl, &self->decls) + vec_foreach_rev(decl, &self->decls) { if (str_eq(decl->name, name)) { - return *decl; + *out_decl = *decl; + return true; } } - return (CDecl){}; + + return false; } void cscope_add(CScope *self, CDecl decl) diff --git a/sources/libs/cc/sema/scope.h b/sources/libs/cc/sema/scope.h index ec03c5d66..1415a4f7f 100644 --- a/sources/libs/cc/sema/scope.h +++ b/sources/libs/cc/sema/scope.h @@ -5,13 +5,13 @@ typedef struct { Vec(CDecl) decls; - CType expected_result; + CType ret; } CScope; void cscope_init(CScope *self, Alloc *alloc); void cscope_deinit(CScope *self); -CDecl cscope_lookup(CScope *self, Str name); +bool cscope_lookup(CScope *self, Str name, CDecl *decl); void cscope_add(CScope *self, CDecl decl); diff --git a/sources/libs/cc/sema/sema.c b/sources/libs/cc/sema/sema.c index e189b00ab..6415c4575 100644 --- a/sources/libs/cc/sema/sema.c +++ b/sources/libs/cc/sema/sema.c @@ -1,15 +1,25 @@ +#include #include #include + void csema_init(CSema *self, Alloc *alloc) { *self = (CSema){}; + self->current_pass = str$("initial"); self->alloc = alloc; vec_init(&self->scopes, alloc); + parse_reports_init(&self->reports, alloc); +} + +void csema_scope_reset(CSema *self) +{ + self->scopes.len = 0; } void csema_deinit(CSema *self) { vec_deinit(&self->scopes); + parse_reports_deinit(&self->reports); } void csema_scope_enter(CSema *self) @@ -32,29 +42,35 @@ void csema_scope_add(CSema *self, CDecl decl) cscope_add(scope, decl); } -CDecl csema_lookup(CSema *self, Str name) +bool csema_lookup(CSema *self, Str name, CDecl *decl) { - vec_foreach(scope, &self->scopes) + vec_foreach_rev(scope, &self->scopes) { - CDecl d = cscope_lookup(scope, name); - if (d.type != CDECL_NIL) - + if (cscope_lookup(scope, name, decl)) { - return d; + return true; } } - return (CDecl){}; + + return false; +} + +bool csema_lookup_current_scope(CSema *self, Str name, CDecl *decl) +{ + CScope *scope = &vec_last(&self->scopes); + return cscope_lookup(scope, name, decl); } CType csema_scope_return_type(CSema *self) { - vec_foreach(scope, &self->scopes) + vec_foreach_rev(scope, &self->scopes) { - if (scope->expected_result.type != CTYPE_INVALID) + if (scope->ret.type != CTYPE_INVALID) { - return scope->expected_result; + return scope->ret; } } + return (CType){.type = CTYPE_INVALID}; } @@ -62,20 +78,13 @@ void csema_scope_enter_func(CSema *self, CType func_type) { CScope scope; cscope_init(&scope, self->alloc); - scope.expected_result = *func_type.func_.ret; + scope.ret = *func_type.func_.ret; - // add each argument in scope vec_foreach(arg, &func_type.func_.params) { - CDecl decl = (CDecl){ - .type = CDECL_VAR, - .name = str_dup(arg->name, self->alloc), - .var_ = { - .type = arg->type, - .expr = cexpr_empty(), - }, - }; + CDecl decl = cdecl_var(arg->name, arg->type, cexpr_empty()); cscope_add(&scope, decl); } + vec_push(&self->scopes, scope); } diff --git a/sources/libs/cc/sema/sema.h b/sources/libs/cc/sema/sema.h index 9d1be7f5e..31f9d83b6 100644 --- a/sources/libs/cc/sema/sema.h +++ b/sources/libs/cc/sema/sema.h @@ -1,11 +1,15 @@ #pragma once +#include #include typedef struct { Vec(CScope) scopes; + ParseReports reports; Alloc *alloc; + + Str current_pass; } CSema; void csema_init(CSema *self, Alloc *alloc); @@ -18,8 +22,25 @@ void csema_scope_enter_func(CSema *self, CType func_type); void csema_scope_leave(CSema *self); +void csema_scope_reset(CSema *self); + void csema_scope_add(CSema *self, CDecl decl); -CDecl csema_lookup(CSema *self, Str name); +bool csema_lookup(CSema *self, Str name, CDecl *decl); + +bool csema_lookup_current_scope(CSema *self, Str name, CDecl *decl); CType csema_scope_return_type(CSema *self); + +#define csema_report$(SELF, LEVEL, REF, FMT, ...) \ + ({ \ + Str _report_str = fmt_str((SELF)->alloc, str$(FMT), any_va$(__VA_ARGS__)); \ + int _id = parse_report_impl(&(SELF)->reports, (SELF)->current_pass, (LEVEL), (REF).ref, _report_str); \ + _id; \ + }) + +#define csema_comment$(SELF, REPORT, REF, FMT, ...) \ + ({ \ + Str _report_str = fmt_str((SELF)->alloc, str$(FMT), any_va$(__VA_ARGS__)); \ + parse_report_comment_impl(&(SELF)->reports, (REPORT), (REF).ref, _report_str); \ + }) diff --git a/sources/libs/cc/sema/visit.c b/sources/libs/cc/sema/visit.c index 5e01bd709..dc1d9bb7b 100644 --- a/sources/libs/cc/sema/visit.c +++ b/sources/libs/cc/sema/visit.c @@ -1,247 +1,264 @@ +#include #include +#include #include -#include -CType csema_value_type(MAYBE_UNUSED CSema *sema, CVal value, Alloc *alloc) +bool cvisit_node_is(void *node, int what, int type) { - /* FIXME: autodetect precision based on architecture */ - switch (value.type) + if (what & CVISIT_DECL) { - case CVAL_FLOAT: - return ctype_float(32); - case CVAL_SIGNED: - return ctype_signed(32); - case CVAL_UNSIGNED: - return ctype_unsigned(32); - case CVAL_STRING: - return ctype_array(ctype_signed(8), value.string_.len, alloc); - default: - return ctype_void(); /* FIXME: better error handling */ + return (int)((CDecl *)node)->type == type; + } + else if (what & CVISIT_EXPR) + { + return (int)((CExpr *)node)->type == type; + } + else if (what & CVISIT_STMT) + { + return (int)((CStmt *)node)->type == type; + } + else if (what & CVISIT_TYPE) + { + return (int)((CType *)node)->type == type; + } + else if (what & CVISIT_UNIT) + { + return true; + } + else + { + return false; } } -static CType csema_decl_type(CSema *self, Str name) +void cvisit_before(CVisites passes, CSema *sema, int what, void *node) { - vec_foreach(scopes, &self->scopes) + slice_foreach$(pass, passes) { - vec_foreach(decls, &scopes->decls) + int mask = what | CVISIT_BEGIN; + if ((pass->what & mask) == mask) { - if (str_eq(decls->name, name)) - { - return decls->sema_type; - } + pass->fn(sema, what, node); } } - log$("not founded symbol: {}", name); - return ctype_void(); } -static CExpr csema_prefix_expr(CSema *sema, CExpr expr, Alloc *alloc) +void cvisit_after(CVisites passes, CSema *sema, int what, void *node) { - *expr.prefix_.expr = csema_expr(sema, *expr.prefix_.expr, alloc); - switch (expr.prefix_.op) - { - case COP_REF: + slice_foreach_rev$(pass, passes) { - expr.sema_type = ctype_ptr(expr.prefix_.expr->sema_type, alloc); - return expr; - } - case COP_DEREF: - { - if (!(expr.prefix_.expr->sema_type.type == CTYPE_PTR)) + int mask = what | CVISIT_END; + if ((pass->what & mask) == mask) { - log$("trying to deref a ptr"); - return expr; + pass->fn(sema, what, node); } - expr.sema_type = *expr.prefix_.expr->sema_type.ptr_.subtype; - return expr; - } - - case COP_NOT: - case COP_DEC: - case COP_INC: - { - expr.sema_type = expr.prefix_.expr->sema_type; - return expr; - } - default: - { - return expr; - } } } -static CExpr csema_postfix_expr(CSema *sema, CExpr expr, Alloc *alloc) + +void cvisit_decl(CVisites passes, CSema *sema, CDecl *decl) { - *expr.postfix_.expr = csema_expr(sema, *expr.postfix_.expr, alloc); - switch (expr.postfix_.op) - { - case COP_DEC: - case COP_INC: + cvisit_before(passes, sema, CVISIT_DECL, decl); + + switch (decl->type) { - expr.sema_type = expr.postfix_.expr->sema_type; - return expr; - } + case CDECL_EMPTY: + break; + + case CDECL_TYPE: + cvisit_type(passes, sema, &decl->type_.type); + break; + + case CDECL_VAR: + cvisit_type(passes, sema, &decl->var_.type); + cvisit_expr(passes, sema, &decl->var_.expr); + break; + + case CDECL_FUNC: + cvisit_type(passes, sema, &decl->func_.type); + cvisit_stmt(passes, sema, &decl->func_.body); + break; + default: - { - return expr; - } + panic$("Unknow decl type"); } + + cvisit_after(passes, sema, CVISIT_DECL, decl); } -static CExpr csema_infix_expr(CSema *sema, CExpr expr, Alloc *alloc) +void cvisit_expr(CVisites passes, CSema *sema, CExpr *expr) { - *expr.infix_.lhs = csema_expr(sema, *expr.infix_.lhs, alloc); - *expr.infix_.rhs = csema_expr(sema, *expr.infix_.rhs, alloc); + cvisit_before(passes, sema, CVISIT_EXPR, expr); - switch (expr.infix_.op) - { - case COP_INDEX: + switch (expr->type) { + case CEXPR_IDENT: + case CEXPR_CONSTANT: + case CEXPR_EMPTY: + break; - if (expr.infix_.lhs->sema_type.type == CTYPE_ARRAY) - { - expr.sema_type = *expr.infix_.lhs->sema_type.array_.subtype; - } - else if (expr.infix_.lhs->sema_type.type == CTYPE_PTR) + case CEXPR_POSTFIX: + case CEXPR_PREFIX: + cvisit_expr(passes, sema, expr->postfix_.expr); + break; + + case CEXPR_INFIX: + cvisit_expr(passes, sema, expr->infix_.lhs); + cvisit_expr(passes, sema, expr->infix_.rhs); + break; + + case CEXPR_CALL: + cvisit_expr(passes, sema, expr->call_.expr); + vec_foreach(arg, &expr->call_.args) { - expr.sema_type = *expr.infix_.lhs->sema_type.ptr_.subtype; + cvisit_expr(passes, sema, arg); } - else + break; + + case CEXPR_CAST: + cvisit_type(passes, sema, &expr->cast_.type); + cvisit_expr(passes, sema, expr->cast_.expr); + break; + + case CEXPR_TERNARY: + cvisit_expr(passes, sema, expr->ternary_.expr_cond); + cvisit_expr(passes, sema, expr->ternary_.expr_true); + cvisit_expr(passes, sema, expr->ternary_.expr_false); + break; + + case CEXPR_INITIALIZER: + cvisit_type(passes, sema, &expr->initializer_.type); + + vec_foreach(init, &expr->initializer_.initializer) { - log$("trying to index a non array"); - expr.sema_type = ctype_void(); + cvisit_expr(passes, sema, init); } - return expr; - } - /* for every unsupported basic op like add sub etc... this works */ + break; + + case CEXPR_LAMBDA: + cvisit_type(passes, sema, &expr->lambda_.type); + cvisit_stmt(passes, sema, expr->lambda_.body); + break; + default: - { - expr.sema_type = expr.infix_.lhs->sema_type; - return expr; - } + panic$("Unknow expr type"); + break; } + + cvisit_after(passes, sema, CVISIT_EXPR, expr); } -CExpr csema_expr(CSema *sema, CExpr expr, Alloc *alloc) +void cvisit_stmt(CVisites passes, CSema *sema, CStmt *stmt) { - switch (expr.type) - { - case CEXPR_CONSTANT: - { - expr.sema_type = csema_value_type(sema, expr.constant_, alloc); - return expr; - } - case CEXPR_IDENT: - { - expr.sema_type = csema_decl_type(sema, expr.ident_); - return expr; - } - case CEXPR_CAST: - { - /* don't check for the moment */ - expr.sema_type = expr.cast_.type; - return expr; - } - case CEXPR_CALL: + cvisit_before(passes, sema, CVISIT_STMT, stmt); + + switch (stmt->type) { - *expr.call_.expr = csema_expr(sema, *expr.call_.expr, alloc); + case CSTMT_DECL: + cvisit_decl(passes, sema, stmt->decl_.decl); + break; - if (expr.call_.expr->sema_type.type != CTYPE_FUNC) - { - log$("not a function! "); - return expr; - } - /* FIXME: no check for this for the moment */ - vec_foreach(arg, &expr.call_.args) + case CSTMT_EXPR: + cvisit_expr(passes, sema, &stmt->expr_.expr); + break; + + case CSTMT_BLOCK: + vec_foreach(v, &stmt->block_.stmts) { - *arg = csema_expr(sema, *arg, alloc); + cvisit_stmt(passes, sema, v); } - expr.sema_type = *expr.call_.expr->sema_type.func_.ret; - return expr; - } - case CEXPR_LAMBDA: - { - expr.sema_type = ctype_void(); - return expr; - } - case CEXPR_PREFIX: - { - return csema_prefix_expr(sema, expr, alloc); - } - case CEXPR_INFIX: - { - return csema_infix_expr(sema, expr, alloc); - } - case CEXPR_POSTFIX: - { - return csema_postfix_expr(sema, expr, alloc); - } + break; + + case CSTMT_IF: + cvisit_expr(passes, sema, &stmt->if_.expr); + cvisit_stmt(passes, sema, stmt->if_.stmt_true); + cvisit_stmt(passes, sema, stmt->if_.stmt_false); + break; + + case CSTMT_FOR: + cvisit_stmt(passes, sema, stmt->for_.init_stmt); + cvisit_expr(passes, sema, &stmt->for_.cond_expr); + cvisit_expr(passes, sema, &stmt->for_.iter_expr); + + cvisit_stmt(passes, sema, stmt->for_.stmt); + break; + + case CSTMT_WHILE: + case CSTMT_DO: + case CSTMT_SWITCH: + cvisit_expr(passes, sema, &stmt->while_.expr); + cvisit_stmt(passes, sema, stmt->while_.stmt); + break; + + case CSTMT_RETURN: + cvisit_expr(passes, sema, &stmt->return_.expr); + break; + + case CSTMT_CASE: + cvisit_expr(passes, sema, &stmt->case_.expr); + break; + default: - { - log$("unhandled expr type: {}", expr.type); - expr.sema_type = ctype_void(); - return expr; - } + panic$("Unknow stmt type"); + break; } + + cvisit_after(passes, sema, CVISIT_STMT, stmt); } -CDecl csema_decl(CSema *sema, CDecl decl, Alloc *alloc) +void cvisit_type(CVisites passes, CSema *sema, CType *type) { - if (csema_lookup(sema, decl.name).type != CDECL_NIL) - { - log$("redefinition of: {}", decl.name); - return cdecl_empty(); - } + cvisit_before(passes, sema, CVISIT_TYPE, type); - switch (decl.type) + switch (type->type) { - case CDECL_TYPE: + case CTYPE_ARRAY: { - decl.sema_type = decl.type_.type; + cvisit_type(passes, sema, type->array_.subtype); break; } - case CDECL_FUNC: - { - decl.sema_type = decl.func_.type; - csema_scope_add(sema, decl); /* we need to add the function to the scope before the body lookup because the body can call the function it self */ - csema_scope_enter_func(sema, decl.func_.type); - decl.func_.body = csema_stmt(sema, decl.func_.body, alloc); - csema_scope_leave(sema); + case CTYPE_PTR: + case CTYPE_REF: + case CTYPE_PARENT: + cvisit_type(passes, sema, type->ref_.subtype); break; - } - case CDECL_VAR: - { - decl.sema_type = decl.var_.type; - decl.var_.expr = csema_expr(sema, decl.var_.expr, alloc); - csema_scope_add(sema, decl); + + case CTYPE_STRUCT: + case CTYPE_UNION: + vec_foreach(member, &type->struct_.members) + { + cvisit_type(passes, sema, &member->type); + } break; - } + + case CTYPE_FUNC: + cvisit_type(passes, sema, type->func_.ret); + + vec_foreach(func_arg, &type->func_.params) + { + cvisit_type(passes, sema, &func_arg->type); + } + break; + default: - { - decl.sema_type = ctype_void(); + panic$("Unknow type type"); break; } - } - return decl; + cvisit_after(passes, sema, CVISIT_TYPE, type); } -CUnit csema_unit(CSema *sema, CUnit unit, Alloc *alloc) +void cvisit_unit(CVisites passes, CSema *sema, CUnit *unit) { - CUnit result = cunit(alloc); + cvisit_before(passes, sema, CVISIT_UNIT, unit); - csema_scope_enter(sema); - - vec_foreach(entry, &unit.units) + vec_foreach(entry, &unit->units) { if (entry->type == CUNIT_DECLARATION) { - cunit_decl(&result, csema_decl(sema, entry->_decl, alloc)); + cvisit_decl(passes, sema, &entry->_decl); } } - csema_scope_leave(sema); - - return result; + cvisit_after(passes, sema, CVISIT_UNIT, unit); } diff --git a/sources/libs/cc/sema/visit.h b/sources/libs/cc/sema/visit.h index 6caabfd10..bb486aac3 100644 --- a/sources/libs/cc/sema/visit.h +++ b/sources/libs/cc/sema/visit.h @@ -1,16 +1,39 @@ #pragma once -#include +#include #include -CVal csema_value(CSema *sema, CVal value, Alloc *alloc); +#define CVISIT_DECL (1 << 0) +#define CVISIT_EXPR (1 << 1) +#define CVISIT_STMT (1 << 2) +#define CVISIT_TYPE (1 << 3) +#define CVISIT_UNIT (1 << 4) -CType csema_type(CSema *sema, CType type, Alloc *alloc); +#define CVISIT_BEGIN (1 << 5) +#define CVISIT_END (1 << 6) -CExpr csema_expr(CSema *sema, CExpr expr, Alloc *alloc); +typedef void CVisitFn(CSema *ctx, int what, void *node); -CStmt csema_stmt(CSema *sema, CStmt stmt, Alloc *alloc); +typedef struct +{ + CVisitFn *fn; + int what; +} CVisit; -CDecl csema_decl(CSema *sema, CDecl decl, Alloc *alloc); +typedef Slice(CVisit) CVisites; -CUnit csema_unit(CSema *sema, CUnit unit, Alloc *alloc); +bool cvisit_node_is(void *node, int what, int type); + +void cvisit_before(CVisites passes, CSema *ctx, int what, void *node); + +void cvisit_after(CVisites passes, CSema *ctx, int what, void *node); + +void cvisit_decl(CVisites passes, CSema *ctx, CDecl *decl); + +void cvisit_expr(CVisites passes, CSema *ctx, CExpr *expr); + +void cvisit_stmt(CVisites passes, CSema *ctx, CStmt *stmt); + +void cvisit_type(CVisites passes, CSema *ctx, CType *type); + +void cvisit_unit(CVisites passes, CSema *ctx, CUnit *unit); diff --git a/sources/libs/cc/sema/visit_statement.c b/sources/libs/cc/sema/visit_statement.c deleted file mode 100644 index 85df3918d..000000000 --- a/sources/libs/cc/sema/visit_statement.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -typedef Vec(CType) CTypeReturned; - -/* for the moment statement don't have type maybe later */ -CStmt csema_stmt(CSema *sema, CStmt stmt, Alloc *alloc) -{ - switch (stmt.type) - { - case CSTMT_DECL: - { - *stmt.decl_.decl = csema_decl(sema, *stmt.decl_.decl, alloc); - break; - } - case CSTMT_EXPR: - { - stmt.expr_.expr = csema_expr(sema, stmt.expr_.expr, alloc); - break; - } - case CSTMT_BLOCK: - { - csema_scope_enter(sema); - vec_foreach(sub_stmt, &stmt.block_.stmts) - { - *sub_stmt = csema_stmt(sema, *sub_stmt, alloc); - } - csema_scope_leave(sema); - break; - } - case CSTMT_IF: - { - stmt.if_.expr = csema_expr(sema, stmt.if_.expr, alloc); - break; - } - case CSTMT_FOR: - { - *stmt.for_.init_stmt = csema_stmt(sema, *stmt.for_.init_stmt, alloc); - stmt.for_.cond_expr = csema_expr(sema, stmt.for_.cond_expr, alloc); - stmt.for_.iter_expr = csema_expr(sema, stmt.for_.iter_expr, alloc); - *stmt.for_.stmt = csema_stmt(sema, *stmt.for_.stmt, alloc); - break; - } - case CSTMT_WHILE: - case CSTMT_DO: - case CSTMT_SWITCH: - { - *stmt.switch_.stmt = csema_stmt(sema, *stmt.switch_.stmt, alloc); - stmt.switch_.expr = csema_expr(sema, stmt.switch_.expr, alloc); - break; - } - case CSTMT_BREAK: - case CSTMT_CONTINUE: - case CSTMT_LABEL: - case CSTMT_DEFAULT: - case CSTMT_GOTO: - { - break; - } - case CSTMT_CASE: - { - stmt.case_.expr = csema_expr(sema, stmt.case_.expr, alloc); - break; - } - case CSTMT_RETURN: - { - stmt.return_.expr = csema_expr(sema, stmt.return_.expr, alloc); - break; - } - default: - { - break; - } - } - return stmt; -} diff --git a/sources/libs/cc/trans.h b/sources/libs/cc/trans.h index a9b38f6c1..3608a2cd7 100644 --- a/sources/libs/cc/trans.h +++ b/sources/libs/cc/trans.h @@ -3,20 +3,22 @@ #include #include -void cc_trans_decl(Emit *emit, CDecl decl); +void ctrans_decl(Emit *emit, CDecl decl); -void cc_trans_expr(Emit *emit, CExpr expr); +void ctrans_expr(Emit *emit, CExpr expr); -void cc_trans_stmt(Emit *emit, CStmt stmt); +void ctrans_stmt(Emit *emit, CStmt stmt); -void cc_trans_type(Emit *emit, CType type); +void ctrans_type(Emit *emit, CType type); -void cc_trans_type_start(Emit *emit, CType type); +void ctrans_type_start(Emit *emit, CType type); -void cc_trans_func_params(Emit *emit, CType type); +void ctrans_func_params(Emit *emit, CType type); -void cc_trans_type_end(Emit *emit, CType type); +void ctrans_type_end(Emit *emit, CType type); -void cc_trans_unit(Emit *emit, CUnit unit); +Str ctrans_type_str(CExpr expr, Alloc *alloc); -void cc_trans_value(Emit *emit, CVal value); +void ctrans_unit(Emit *emit, CUnit unit); + +void ctrans_value(Emit *emit, CVal value); diff --git a/sources/libs/cc/trans/decl.c b/sources/libs/cc/trans/decl.c index bc023c9ec..e273ed7d3 100644 --- a/sources/libs/cc/trans/decl.c +++ b/sources/libs/cc/trans/decl.c @@ -1,6 +1,6 @@ #include -static void cc_trans_decl_attr(Emit *emit, CDeclAttr attr) +static void ctrans_decl_attr(Emit *emit, CDeclAttr attr) { if (attr & CDECL_AUTO) { @@ -33,9 +33,9 @@ static void cc_trans_decl_attr(Emit *emit, CDeclAttr attr) } } -void cc_trans_decl(Emit *emit, CDecl decl) +void ctrans_decl(Emit *emit, CDecl decl) { - cc_trans_decl_attr(emit, decl.attr); + ctrans_decl_attr(emit, decl.attr); if (decl.type == CDECL_TYPE) { @@ -46,26 +46,26 @@ void cc_trans_decl(Emit *emit, CDecl decl) emit_fmt$(emit, "typedef "); } - cc_trans_type_start(emit, decl.type_.type); + ctrans_type_start(emit, decl.type_.type); if (is_typedef) { emit_fmt$(emit, " {}", decl.name); } - cc_trans_type_end(emit, decl.type_.type); + ctrans_type_end(emit, decl.type_.type); } else if (decl.type == CDECL_VAR) { - cc_trans_type_start(emit, decl.var_.type); + ctrans_type_start(emit, decl.var_.type); emit_fmt$(emit, " {} ", decl.name); - cc_trans_type_end(emit, decl.var_.type); + ctrans_type_end(emit, decl.var_.type); if (decl.var_.expr.type != CEXPR_INVALID && decl.var_.expr.type != CEXPR_EMPTY) { emit_fmt$(emit, "="); - cc_trans_expr(emit, decl.var_.expr); + ctrans_expr(emit, decl.var_.expr); } } else if (decl.type == CDECL_FUNC) @@ -73,15 +73,15 @@ void cc_trans_decl(Emit *emit, CDecl decl) CType func_type = decl.func_.type; // Declarator - cc_trans_type_start(emit, func_type); + ctrans_type_start(emit, func_type); emit_fmt$(emit, " {}", decl.name); - cc_trans_type_end(emit, func_type); + ctrans_type_end(emit, func_type); // Body if (decl.func_.body.type != CSTMT_EMPTY) { emit_fmt$(emit, "\n", decl.name); - cc_trans_stmt(emit, decl.func_.body); + ctrans_stmt(emit, decl.func_.body); } else { diff --git a/sources/libs/cc/trans/expr.c b/sources/libs/cc/trans/expr.c index 4755d4706..5df93de39 100644 --- a/sources/libs/cc/trans/expr.c +++ b/sources/libs/cc/trans/expr.c @@ -1,12 +1,14 @@ #include #include -static void cc_trans_op_fix(Emit *emit, COp op) +#include "cc/builder.h" + +static void ctrans_op_fix(Emit *emit, COp op) { emit_fmt$(emit, "{}", cop_to_str(op)); } -static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) +static void ctrans_expr_pre(Emit *emit, CExpr expr, int parent_pre) { int pre = cexpr_pre(&expr); @@ -21,7 +23,7 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) break; case CEXPR_CONSTANT: - cc_trans_value(emit, expr.constant_); + ctrans_value(emit, expr.constant_); break; case CEXPR_IDENT: @@ -32,26 +34,26 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) break; case CEXPR_PREFIX: - cc_trans_op_fix(emit, expr.prefix_.op); + ctrans_op_fix(emit, expr.prefix_.op); if (expr.prefix_.expr != nullptr) { - cc_trans_expr_pre(emit, *expr.prefix_.expr, pre); + ctrans_expr_pre(emit, *expr.prefix_.expr, pre); } break; case CEXPR_POSTFIX: if (expr.postfix_.expr != nullptr) { - cc_trans_expr_pre(emit, *expr.postfix_.expr, pre); + ctrans_expr_pre(emit, *expr.postfix_.expr, pre); } - cc_trans_op_fix(emit, expr.postfix_.op); + ctrans_op_fix(emit, expr.postfix_.op); break; case CEXPR_INFIX: - cc_trans_expr_pre(emit, *expr.infix_.lhs, pre); - cc_trans_op_fix(emit, expr.infix_.op); - cc_trans_expr_pre(emit, *expr.infix_.rhs, pre); + ctrans_expr_pre(emit, *expr.infix_.lhs, pre); + ctrans_op_fix(emit, expr.infix_.op); + ctrans_expr_pre(emit, *expr.infix_.rhs, pre); if (expr.infix_.op == COP_INDEX) { emit_fmt$(emit, "]"); @@ -59,7 +61,7 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) break; case CEXPR_CALL: - cc_trans_expr_pre(emit, *expr.call_.expr, pre); + ctrans_expr_pre(emit, *expr.call_.expr, pre); emit_fmt$(emit, "("); bool first = true; vec_foreach_v(v, &expr.call_.args) @@ -73,29 +75,29 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) emit_fmt$(emit, ", "); } - cc_trans_expr_pre(emit, v, CEXPR_MAX_PRECEDENCE); + ctrans_expr_pre(emit, v, CEXPR_MAX_PRECEDENCE); } emit_fmt$(emit, ")"); break; case CEXPR_CAST: emit_fmt$(emit, "("); - cc_trans_type(emit, expr.cast_.type); + ctrans_type(emit, expr.cast_.type); emit_fmt$(emit, ")"); - cc_trans_expr_pre(emit, *expr.cast_.expr, pre); + ctrans_expr_pre(emit, *expr.cast_.expr, pre); break; case CEXPR_TERNARY: - cc_trans_expr_pre(emit, *expr.ternary_.expr_cond, pre); + ctrans_expr_pre(emit, *expr.ternary_.expr_cond, pre); emit_fmt$(emit, " ? "); - cc_trans_expr_pre(emit, *expr.ternary_.expr_true, pre); + ctrans_expr_pre(emit, *expr.ternary_.expr_true, pre); emit_fmt$(emit, " : "); - cc_trans_expr_pre(emit, *expr.ternary_.expr_false, pre); + ctrans_expr_pre(emit, *expr.ternary_.expr_false, pre); break; case CEXPR_INITIALIZER: emit_fmt$(emit, "("); - cc_trans_type(emit, expr.initializer_.type); + ctrans_type(emit, expr.initializer_.type); emit_fmt$(emit, ")"); emit_fmt$(emit, "{{\n"); @@ -103,7 +105,7 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) vec_foreach_v(v, &expr.initializer_.initializer) { - cc_trans_expr_pre(emit, v, CEXPR_MAX_PRECEDENCE); + ctrans_expr_pre(emit, v, CEXPR_MAX_PRECEDENCE); emit_fmt$(emit, ",\n"); } @@ -113,8 +115,8 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) case CEXPR_LAMBDA: emit_fmt$(emit, "[]"); - cc_trans_func_params(emit, expr.lambda_.type); - cc_trans_stmt(emit, *expr.lambda_.body); + ctrans_func_params(emit, expr.lambda_.type); + ctrans_stmt(emit, *expr.lambda_.body); break; default: @@ -127,7 +129,7 @@ static void cc_trans_expr_pre(Emit *emit, CExpr expr, int parent_pre) } } -void cc_trans_expr(Emit *emit, CExpr expr) +void ctrans_expr(Emit *emit, CExpr expr) { - cc_trans_expr_pre(emit, expr, CEXPR_MAX_PRECEDENCE); + ctrans_expr_pre(emit, expr, CEXPR_MAX_PRECEDENCE); } diff --git a/sources/libs/cc/trans/stmt.c b/sources/libs/cc/trans/stmt.c index cc136152e..e4a6b6820 100644 --- a/sources/libs/cc/trans/stmt.c +++ b/sources/libs/cc/trans/stmt.c @@ -1,6 +1,6 @@ #include -static bool cc_trans_should_stmt_endline(CStmtType type) +static bool ctrans_should_stmt_endline(CStmtType type) { if (type == CSTMT_BLOCK || type == CSTMT_DEFAULT || @@ -13,7 +13,7 @@ static bool cc_trans_should_stmt_endline(CStmtType type) return true; } -void cc_trans_stmt(Emit *emit, CStmt stmt) +void ctrans_stmt(Emit *emit, CStmt stmt) { switch (stmt.type) { @@ -21,11 +21,11 @@ void cc_trans_stmt(Emit *emit, CStmt stmt) break; case CSTMT_DECL: - cc_trans_decl(emit, *stmt.decl_.decl); + ctrans_decl(emit, *stmt.decl_.decl); return; case CSTMT_EXPR: - cc_trans_expr(emit, stmt.expr_.expr); + ctrans_expr(emit, stmt.expr_.expr); return; case CSTMT_BLOCK: @@ -34,8 +34,8 @@ void cc_trans_stmt(Emit *emit, CStmt stmt) vec_foreach_v(v, &stmt.block_.stmts) { - cc_trans_stmt(emit, v); - if (cc_trans_should_stmt_endline(v.type)) + ctrans_stmt(emit, v); + if (ctrans_should_stmt_endline(v.type)) { emit_fmt$(emit, ";"); } @@ -49,18 +49,18 @@ void cc_trans_stmt(Emit *emit, CStmt stmt) case CSTMT_IF: emit_fmt$(emit, "if ("); - cc_trans_expr(emit, stmt.if_.expr); + ctrans_expr(emit, stmt.if_.expr); emit_fmt$(emit, ")\n"); if (stmt.if_.stmt_true->type != CSTMT_BLOCK) { emit_ident(emit); - cc_trans_stmt(emit, *stmt.if_.stmt_true); + ctrans_stmt(emit, *stmt.if_.stmt_true); emit_deident(emit); } else { - cc_trans_stmt(emit, *stmt.if_.stmt_true); + ctrans_stmt(emit, *stmt.if_.stmt_true); } if (stmt.if_.stmt_false->type != CSTMT_EMPTY) @@ -69,58 +69,58 @@ void cc_trans_stmt(Emit *emit, CStmt stmt) if (stmt.if_.stmt_true->type != CSTMT_BLOCK) { emit_ident(emit); - cc_trans_stmt(emit, *stmt.if_.stmt_false); + ctrans_stmt(emit, *stmt.if_.stmt_false); emit_deident(emit); } else { - cc_trans_stmt(emit, *stmt.if_.stmt_false); + ctrans_stmt(emit, *stmt.if_.stmt_false); } } return; case CSTMT_FOR: emit_fmt$(emit, "for ("); - cc_trans_stmt(emit, *stmt.for_.init_stmt); + ctrans_stmt(emit, *stmt.for_.init_stmt); emit_fmt$(emit, "; "); - cc_trans_expr(emit, stmt.for_.cond_expr); + ctrans_expr(emit, stmt.for_.cond_expr); emit_fmt$(emit, "; "); - cc_trans_expr(emit, stmt.for_.iter_expr); + ctrans_expr(emit, stmt.for_.iter_expr); emit_fmt$(emit, ")\n"); - cc_trans_stmt(emit, *stmt.for_.stmt); + ctrans_stmt(emit, *stmt.for_.stmt); return; case CSTMT_WHILE: emit_fmt$(emit, "while ("); - cc_trans_expr(emit, stmt.while_.expr); + ctrans_expr(emit, stmt.while_.expr); emit_fmt$(emit, ") \n"); - cc_trans_stmt(emit, *stmt.while_.stmt); + ctrans_stmt(emit, *stmt.while_.stmt); return; case CSTMT_DO: emit_fmt$(emit, "do \n "); - cc_trans_stmt(emit, *stmt.do_.stmt); + ctrans_stmt(emit, *stmt.do_.stmt); emit_fmt$(emit, "while ("); - cc_trans_expr(emit, stmt.do_.expr); + ctrans_expr(emit, stmt.do_.expr); emit_fmt$(emit, ") \n"); return; case CSTMT_SWITCH: emit_fmt$(emit, "switch ("); - cc_trans_expr(emit, stmt.while_.expr); + ctrans_expr(emit, stmt.while_.expr); emit_fmt$(emit, ")\n"); - cc_trans_stmt(emit, *stmt.while_.stmt); + ctrans_stmt(emit, *stmt.while_.stmt); return; case CSTMT_RETURN: emit_fmt$(emit, "return "); - cc_trans_expr(emit, stmt.return_.expr); + ctrans_expr(emit, stmt.return_.expr); return; case CSTMT_GOTO: @@ -141,7 +141,7 @@ void cc_trans_stmt(Emit *emit, CStmt stmt) case CSTMT_CASE: emit_fmt$(emit, "case "); - cc_trans_expr(emit, stmt.case_.expr); + ctrans_expr(emit, stmt.case_.expr); emit_fmt$(emit, ":"); return; diff --git a/sources/libs/cc/trans/type.c b/sources/libs/cc/trans/type.c index b7b008c20..d63683e57 100644 --- a/sources/libs/cc/trans/type.c +++ b/sources/libs/cc/trans/type.c @@ -1,24 +1,25 @@ +#include #include -static void cc_trans_member(Emit *emit, CTypeMember type) +static void ctrans_member(Emit *emit, CTypeMember type) { - cc_trans_type_start(emit, type.type); + ctrans_type_start(emit, type.type); emit_fmt$(emit, " {}", type.name); - cc_trans_type_end(emit, type.type); + ctrans_type_end(emit, type.type); } -static void cc_trans_constant(Emit *emit, CTypeConst member) +static void ctrans_constant(Emit *emit, CTypeConst member) { emit_fmt$(emit, "{}", member.name); if (member.value.type != CVAL_INVALID) { emit_fmt$(emit, " = "); - cc_trans_value(emit, member.value); + ctrans_value(emit, member.value); } } -static void cc_trans_type_attr(Emit *emit, CTypeAttr attr) +static void ctrans_type_attr(Emit *emit, CTypeAttr attr) { if (attr & CTYPE_CONST) { @@ -36,33 +37,33 @@ static void cc_trans_type_attr(Emit *emit, CTypeAttr attr) } } -void cc_trans_type(Emit *emit, CType type) +void ctrans_type(Emit *emit, CType type) { - cc_trans_type_start(emit, type); - cc_trans_type_end(emit, type); + ctrans_type_start(emit, type); + ctrans_type_end(emit, type); } -void cc_trans_type_start(Emit *emit, CType type) +void ctrans_type_start(Emit *emit, CType type) { if (type.type == CTYPE_NAME) { emit_fmt$(emit, type.name); - cc_trans_type_attr(emit, type.attr); + ctrans_type_attr(emit, type.attr); } else if (type.type == CTYPE_PTR) { - cc_trans_type_start(emit, *type.ptr_.subtype); + ctrans_type_start(emit, *type.ptr_.subtype); emit_fmt$(emit, "*"); - cc_trans_type_attr(emit, type.attr); + ctrans_type_attr(emit, type.attr); } else if (type.type == CTYPE_PARENT) { - cc_trans_type_start(emit, *type.ptr_.subtype); + ctrans_type_start(emit, *type.ptr_.subtype); emit_fmt$(emit, "("); } else if (type.type == CTYPE_FUNC) { - cc_trans_type(emit, *type.func_.ret); // return + ctrans_type(emit, *type.func_.ret); // return } else if ((type.type == CTYPE_STRUCT || type.type == CTYPE_UNION) && type.struct_.members.len != 0) @@ -81,13 +82,13 @@ void cc_trans_type_start(Emit *emit, CType type) emit_fmt$(emit, " {}", type.name); } - cc_trans_type_attr(emit, type.attr); + ctrans_type_attr(emit, type.attr); emit_fmt$(emit, "\n{{\n"); emit_ident(emit); vec_foreach_v(v, &type.struct_.members) { - cc_trans_member(emit, v); + ctrans_member(emit, v); emit_fmt$(emit, ";\n"); } @@ -108,27 +109,27 @@ void cc_trans_type_start(Emit *emit, CType type) vec_foreach_v(v, &type.enum_.constants) { - cc_trans_constant(emit, v); + ctrans_constant(emit, v); emit_fmt$(emit, ",\n"); } emit_deident(emit); emit_fmt$(emit, "}}"); - cc_trans_type_attr(emit, type.attr); + ctrans_type_attr(emit, type.attr); } else if (type.type == CTYPE_ARRAY) { - cc_trans_type_attr(emit, type.attr); - cc_trans_type_start(emit, *type.array_.subtype); + ctrans_type_attr(emit, type.attr); + ctrans_type_start(emit, *type.array_.subtype); } else { - emit_fmt$(emit, ctype_to_str(type.type)); + emit_fmt$(emit, ctype_to_str(type)); } } -void cc_trans_func_params(Emit *emit, CType type) +void ctrans_func_params(Emit *emit, CType type) { emit_fmt$(emit, "("); @@ -140,26 +141,26 @@ void cc_trans_func_params(Emit *emit, CType type) emit_fmt$(emit, ", "); } first = false; - cc_trans_member(emit, v); + ctrans_member(emit, v); } emit_fmt$(emit, ")"); } -void cc_trans_type_end(Emit *emit, CType type) +void ctrans_type_end(Emit *emit, CType type) { if (type.type == CTYPE_PTR) { - cc_trans_type_end(emit, *type.ptr_.subtype); + ctrans_type_end(emit, *type.ptr_.subtype); } else if (type.type == CTYPE_PARENT) { emit_fmt$(emit, ")"); - cc_trans_type_end(emit, *type.ptr_.subtype); + ctrans_type_end(emit, *type.ptr_.subtype); } else if (type.type == CTYPE_FUNC) { - cc_trans_func_params(emit, type); - cc_trans_type_attr(emit, type.attr); + ctrans_func_params(emit, type); + ctrans_type_attr(emit, type.attr); } else if (type.type == CTYPE_ARRAY) { @@ -171,6 +172,19 @@ void cc_trans_type_end(Emit *emit, CType type) { emit_fmt$(emit, "[{}]", type.array_.size); } - cc_trans_type_end(emit, *type.ptr_.subtype); + ctrans_type_end(emit, *type.ptr_.subtype); } } + +Str ctrans_type_str(CExpr expr, Alloc *alloc) +{ + Emit emit; + Buf buf = {}; + buf_init(&buf, 18, alloc); + emit_init(&emit, buf_writer(&buf)); + + ctrans_type(&emit, expr.sema_type); + + emit_deinit(&emit); + return buf_str(&buf); +} diff --git a/sources/libs/cc/trans/unit.c b/sources/libs/cc/trans/unit.c index 1efc66214..9da2378dd 100644 --- a/sources/libs/cc/trans/unit.c +++ b/sources/libs/cc/trans/unit.c @@ -1,6 +1,6 @@ #include -static void cc_trans_include(Emit *emit, CInclude path) +static void ctrans_include(Emit *emit, CInclude path) { emit_fmt$(emit, "#include "); @@ -14,14 +14,14 @@ static void cc_trans_include(Emit *emit, CInclude path) } } -static void cc_trans_pragma(Emit *emit, CPragma pragma) +static void ctrans_pragma(Emit *emit, CPragma pragma) { emit_fmt$(emit, "#pragma "); emit_fmt$(emit, pragma.text); emit_fmt$(emit, "\n"); } -static void cc_trans_define(Emit *emit, CDefine define) +static void ctrans_define(Emit *emit, CDefine define) { emit_fmt$(emit, "#define "); emit_fmt$(emit, define.name); @@ -44,13 +44,13 @@ static void cc_trans_define(Emit *emit, CDefine define) emit_fmt$(emit, ")"); } emit_fmt$(emit, " "); - cc_trans_expr(emit, define.expression); + ctrans_expr(emit, define.expression); emit_fmt$(emit, "\n"); } -void cc_trans_unit(Emit *emit, CUnit unit) +void ctrans_unit(Emit *emit, CUnit unit) { - CUnitType prev_type = CUNIT_NONE; + CUnitType prev_type = CUNIT_INVALID; vec_foreach_v(entry, &unit.units) { @@ -62,17 +62,17 @@ void cc_trans_unit(Emit *emit, CUnit unit) emit_fmt$(emit, "\n"); } - cc_trans_include(emit, entry._include); + ctrans_include(emit, entry._include); break; case CUNIT_PRAGMA: - cc_trans_pragma(emit, entry._pragma); + ctrans_pragma(emit, entry._pragma); break; case CUNIT_DECLARATION: emit_fmt$(emit, "\n"); - cc_trans_decl(emit, entry._decl); + ctrans_decl(emit, entry._decl); if (entry._decl.type != CDECL_FUNC) { @@ -88,7 +88,7 @@ void cc_trans_unit(Emit *emit, CUnit unit) emit_fmt$(emit, "\n"); } - cc_trans_define(emit, entry._define); + ctrans_define(emit, entry._define); break; default: diff --git a/sources/libs/cc/trans/val.c b/sources/libs/cc/trans/val.c index ab69c9ce4..bd9202083 100644 --- a/sources/libs/cc/trans/val.c +++ b/sources/libs/cc/trans/val.c @@ -1,15 +1,15 @@ #include #include -void cc_trans_value(Emit *emit, CVal value) +void ctrans_value(Emit *emit, CVal value) { switch (value.type) { - case CVAL_SIGNED: + case CVAL_INT: emit_fmt$(emit, "{}", value.signed_); break; - case CVAL_UNSIGNED: + case CVAL_UINT: emit_fmt$(emit, "{}", value.unsigned_); break; @@ -18,7 +18,7 @@ void cc_trans_value(Emit *emit, CVal value) break; case CVAL_STRING: - emit_fmt$(emit, "\"{}\"", value.string_); + emit_fmt$(emit, "\"{}\"", value.str_); break; default: diff --git a/sources/libs/codec-ssfn2/ssfn2.c b/sources/libs/codec-ssfn2/ssfn2.c index 704fbbdd8..848656fef 100644 --- a/sources/libs/codec-ssfn2/ssfn2.c +++ b/sources/libs/codec-ssfn2/ssfn2.c @@ -4,7 +4,7 @@ #include "ssfn2.h" -static MaybeError ssfn2_load_string(IoReader reader, char *dst) +static MaybeError ssfn2_load_str(IoReader reader, char *dst) { for (size_t i = 0; i < SSFN2_MAX_STR_LEN; i++) { @@ -21,14 +21,14 @@ static MaybeError ssfn2_load_string(IoReader reader, char *dst) return SUCCESS; } -static MaybeError ssfn2_load_stringtable(IoReader reader, SSFN2Font *font) +static MaybeError ssfn2_load_strtable(IoReader reader, SSFN2Font *font) { - TRY(MaybeError, ssfn2_load_string(reader, font->stringtable.font_name)); - TRY(MaybeError, ssfn2_load_string(reader, font->stringtable.family_name)); - TRY(MaybeError, ssfn2_load_string(reader, font->stringtable.subfamily_name)); - TRY(MaybeError, ssfn2_load_string(reader, font->stringtable.revision)); - TRY(MaybeError, ssfn2_load_string(reader, font->stringtable.manufacturer)); - TRY(MaybeError, ssfn2_load_string(reader, font->stringtable.license)); + TRY(MaybeError, ssfn2_load_str(reader, font->strtable.font_name)); + TRY(MaybeError, ssfn2_load_str(reader, font->strtable.family_name)); + TRY(MaybeError, ssfn2_load_str(reader, font->strtable.subfamily_name)); + TRY(MaybeError, ssfn2_load_str(reader, font->strtable.revision)); + TRY(MaybeError, ssfn2_load_str(reader, font->strtable.manufacturer)); + TRY(MaybeError, ssfn2_load_str(reader, font->strtable.license)); return SUCCESS; } @@ -269,7 +269,7 @@ static void ssfn2_compute_weight(SSFN2Font *font) { font->weight = GFX_FONT_REGULAR; - Str subfamily = str$(font->stringtable.subfamily_name); + Str subfamily = str$(font->strtable.subfamily_name); // Weights if (str_first(subfamily, str$("Black")) >= 0) font->weight = GFX_FONT_BLACK; @@ -312,8 +312,9 @@ static MaybeError ssfn2_load_internal(IoRSeek rseek, SSFN2Collection *collection { SSFN2Font font; font.font_start = start; + TRY(MaybeError, io_read$(rseek, (uint8_t *)&font.header, sizeof(SSFN2FontHeader))); - TRY(MaybeError, ssfn2_load_stringtable(io_reader$(rseek), &font)); + TRY(MaybeError, ssfn2_load_strtable(io_reader$(rseek), &font)); font.glyphs = alloc_make_array(alloc, SSFN2Glyph, 0x110000); diff --git a/sources/libs/codec-ssfn2/ssfn2.h b/sources/libs/codec-ssfn2/ssfn2.h index e87492065..814bf0b64 100644 --- a/sources/libs/codec-ssfn2/ssfn2.h +++ b/sources/libs/codec-ssfn2/ssfn2.h @@ -19,7 +19,7 @@ typedef struct size_t font_start; float weight; SSFN2FontHeader header; - SSFN2StringTable stringtable; + SSFN2StringTable strtable; SSFN2Glyph *glyphs; /* glyphs array */ } SSFN2Font; diff --git a/sources/libs/elf/elf.c b/sources/libs/elf/elf.c index 091881461..71e3f6792 100644 --- a/sources/libs/elf/elf.c +++ b/sources/libs/elf/elf.c @@ -8,7 +8,7 @@ bool elf_validate(Elf64Header const *header) header->ident.magics[3] == 'F'; } -Str elf_string(Elf64Header const *header, size_t offset) +Str elf_str(Elf64Header const *header, size_t offset) { Elf64SectionHeader const *strings = elf_section_by_index(header, header->strings_section_index); @@ -57,7 +57,7 @@ Elf64SectionHeader const *elf_section_by_name(Elf64Header const *header, Str nam for (size_t i = 0; i < header->sections_count; i++) { - Str section_name = elf_string(header, section->name); + Str section_name = elf_str(header, section->name); if (str_eq(section_name, name)) { diff --git a/sources/libs/elf/elf.h b/sources/libs/elf/elf.h index 4c75c70c3..ece8d8888 100644 --- a/sources/libs/elf/elf.h +++ b/sources/libs/elf/elf.h @@ -114,7 +114,7 @@ typedef struct PACKED bool elf_validate(Elf64Header const *header); -Str elf_string(Elf64Header const *header, size_t offset); +Str elf_str(Elf64Header const *header, size_t offset); Str elf_manifest(Elf64Header const *header); diff --git a/sources/libs/hw/fdt/fdt.c b/sources/libs/hw/fdt/fdt.c index b98e4ad14..858307f50 100644 --- a/sources/libs/hw/fdt/fdt.c +++ b/sources/libs/hw/fdt/fdt.c @@ -43,7 +43,7 @@ static FdtNode fdt_tok2node(FdtTokBegin *raw_node, FdtHeader *header) static FdtProp fdt_tok2prop(FdtTokProp *raw_prop, FdtHeader *header) { - Str node_name = str$((char const *)((uintptr_t)header + be_load$(header->strings_offset) + be_load$(raw_prop->name_offset))); + Str node_name = str$((char const *)((uintptr_t)header + be_load$(header->strs_offset) + be_load$(raw_prop->name_offset))); return (FdtProp){ .name = node_name, @@ -271,8 +271,8 @@ static void fdt_dump_props_value(FdtProp *prop, Emit *emit) } if (prop->value.len > 2) { - Str as_string = str_n$(prop->value.len, (char *)prop->value.buf); - emit_fmt$(emit, "- as string: {} \n", as_string); + Str as_str = str_n$(prop->value.len, (char *)prop->value.buf); + emit_fmt$(emit, "- as string: {} \n", as_str); } emit_fmt$(emit, "- as data: "); diff --git a/sources/libs/hw/fdt/fdt.h b/sources/libs/hw/fdt/fdt.h index c77451bd8..de09ca300 100644 --- a/sources/libs/hw/fdt/fdt.h +++ b/sources/libs/hw/fdt/fdt.h @@ -7,12 +7,12 @@ typedef struct PACKED be_uint32_t magic; be_uint32_t size; be_uint32_t structure_offset; - be_uint32_t strings_offset; + be_uint32_t strs_offset; be_uint32_t memory_reservation_offset; be_uint32_t version; be_uint32_t last_comp_version; be_uint32_t boot_cpuid_phys; - be_uint32_t strings_size; + be_uint32_t strs_size; be_uint32_t structure_size; } FdtHeader; diff --git a/sources/libs/idl/cgen/binding.c b/sources/libs/idl/cgen/binding.c index 1b5d9dbf5..c8fa8329b 100644 --- a/sources/libs/idl/cgen/binding.c +++ b/sources/libs/idl/cgen/binding.c @@ -6,7 +6,7 @@ CExpr idl_cgen_binding(IdlMethod method, IdlIface const iface, Alloc *alloc) { CExpr init = cexpr_initializer(ctype_ident(str$("IdlBinding")), alloc); - cexpr_member(&init, cexpr_constant(cval_unsigned(iface.id))); + cexpr_member(&init, cexpr_constant(cval_uint(iface.id))); CExpr nullptr_ident = cexpr_ident(str$("nullptr")); @@ -31,7 +31,7 @@ CExpr idl_cgen_binding(IdlMethod method, IdlIface const iface, Alloc *alloc) } else { - cexpr_member(&init, cexpr_constant(cval$(-1))); + cexpr_member(&init, cexpr_constant(cval_int(-1))); cexpr_member(&init, nullptr_ident); cexpr_member(&init, nullptr_ident); } diff --git a/sources/libs/idl/cgen/header.c b/sources/libs/idl/cgen/header.c index 2cddb4a5c..2505e6847 100644 --- a/sources/libs/idl/cgen/header.c +++ b/sources/libs/idl/cgen/header.c @@ -7,7 +7,7 @@ void idl_cgen_iface_header(CUnit *unit, IdlModule const module, IdlIface const i CType vtable = ctype_struct(alloc); CType msgtype = ctype_enum(alloc); - cunit_define(unit, fmt_str$(alloc, "IPC_{case-constant}_PROTO", iface.name), cexpr_constant(cval_unsigned(iface.id)), alloc); + cunit_define(unit, fmt_str$(alloc, "IPC_{case-constant}_PROTO", iface.name), cexpr_constant(cval_uint(iface.id)), alloc); int i = 0; vec_foreach_v(method, &iface.methods) @@ -20,8 +20,8 @@ void idl_cgen_iface_header(CUnit *unit, IdlModule const module, IdlIface const i cunit_decl(unit, cdecl_type(name, handler_type)); cunit_decl(unit, cdecl_func(fmt_str$(alloc, "{}_rpc", method.name), method_type, cstmt_empty())); - ctype_constant(&msgtype, fmt_str$(alloc, "MSG_{case-constant}_REQ", method.name), cval_unsigned(i++)); - ctype_constant(&msgtype, fmt_str$(alloc, "MSG_{case-constant}_RESP", method.name), cval_unsigned(i++)); + ctype_constant(&msgtype, fmt_str$(alloc, "MSG_{case-constant}_REQ", method.name), cval_uint(i++)); + ctype_constant(&msgtype, fmt_str$(alloc, "MSG_{case-constant}_RESP", method.name), cval_uint(i++)); } cunit_decl(unit, cdecl_type(fmt_str$(alloc, "{}Msgs", iface.name), msgtype)); diff --git a/sources/libs/idl/cgen/provider.c b/sources/libs/idl/cgen/provider.c index 04bb28966..5339954ca 100644 --- a/sources/libs/idl/cgen/provider.c +++ b/sources/libs/idl/cgen/provider.c @@ -23,7 +23,7 @@ CDecl idl_cgen_provider_func(IdlIface const iface, Alloc *alloc) CExpr expr = cexpr_call(alloc, cexpr_ident(str$("ipc_object_provide"))); cexpr_member(&expr, cexpr_ident(str$("object"))); - cexpr_member(&expr, cexpr_constant(cval_unsigned(iface.id))); + cexpr_member(&expr, cexpr_constant(cval_uint(iface.id))); cexpr_member(&expr, cexpr_ident(fmt_str$(alloc, "__IDL_PRIVATE__{case-snake}_dispatch_rpc", iface.name))); cexpr_member(&expr, cexpr_ident(str$("vtable"))); diff --git a/sources/libs/idl/cgen/types.c b/sources/libs/idl/cgen/types.c index f651cfaf2..bb5c6b689 100644 --- a/sources/libs/idl/cgen/types.c +++ b/sources/libs/idl/cgen/types.c @@ -18,7 +18,7 @@ CType idl_cgen_decl_enum(IdlType type, Alloc *alloc) vec_foreach_v(member, &type.enum_.members) { - ctype_constant(&ctype, member.name, cval_signed(member.value)); + ctype_constant(&ctype, member.name, cval_int(member.value)); } return ctype; diff --git a/sources/libs/json/emit.c b/sources/libs/json/emit.c index bce54933a..40cdb8898 100644 --- a/sources/libs/json/emit.c +++ b/sources/libs/json/emit.c @@ -1,7 +1,7 @@ #include #include -void json_emit_string(Str str, Emit *emit) +void json_emit_str(Str str, Emit *emit) { emit_fmt$(emit, "\""); @@ -75,7 +75,7 @@ void json_emit(Json const json, Emit *emit) } emit_fmt$(emit, "\n"); - json_emit_string(k, emit); + json_emit_str(k, emit); emit_fmt$(emit, ": "); json_emit(v, emit); @@ -93,7 +93,7 @@ void json_emit(Json const json, Emit *emit) break; case JSON_STRING: - json_emit_string(json.string, emit); + json_emit_str(json.str, emit); break; case JSON_NUMBER: diff --git a/sources/libs/json/objects.c b/sources/libs/json/objects.c index 16b45005d..ae9ae66af 100644 --- a/sources/libs/json/objects.c +++ b/sources/libs/json/objects.c @@ -109,6 +109,6 @@ Json json_str(Str str) { return (Json){ .type = JSON_STRING, - .string = str, + .str = str, }; } diff --git a/sources/libs/json/objects.h b/sources/libs/json/objects.h index 5b4cc2111..b52ff7c7a 100644 --- a/sources/libs/json/objects.h +++ b/sources/libs/json/objects.h @@ -5,12 +5,14 @@ typedef enum { JSON_NULL, + JSON_TRUE, JSON_FALSE, JSON_ARRAY, JSON_OBJECT, JSON_STRING, JSON_NUMBER, + JSON_ERROR } JsonType; @@ -27,7 +29,7 @@ struct _Json { JsonObj object; JsonArr array; - Str string; + Str str; long number; }; }; diff --git a/sources/libs/json/parser.c b/sources/libs/json/parser.c index 9a242bdd7..c2fd14993 100644 --- a/sources/libs/json/parser.c +++ b/sources/libs/json/parser.c @@ -1,6 +1,6 @@ -#include #include #include +#include static bool json_skip_comment(Scan *scan) { @@ -28,7 +28,7 @@ static void json_skip_space_and_comment(Scan *scan) ; } -static int is_closing_string(int c) +static int is_closing_str(int c) { return c != '"'; } @@ -37,7 +37,7 @@ static Str parse_str(Scan *scan) { json_skip_space_and_comment(scan); scan_expect(scan, '"'); - Str name = scan_eat_match(scan, is_closing_string); + Str name = scan_eat_match(scan, is_closing_str); scan_expect(scan, '"'); json_skip_space_and_comment(scan); @@ -108,7 +108,7 @@ Json json_parse(Scan *scan, Alloc *alloc) { json_skip_space_and_comment(scan); - if (scan_curr(scan) == '"') // string + if (scan_curr(scan) == '"') { return json_str(parse_str(scan)); } diff --git a/sources/libs/stdc-ansi/stdlib.h b/sources/libs/stdc-ansi/stdlib.h index a1fc972e8..92e45cb8a 100644 --- a/sources/libs/stdc-ansi/stdlib.h +++ b/sources/libs/stdc-ansi/stdlib.h @@ -91,7 +91,7 @@ int at_quick_exit(void (*func)(void)); _Noreturn void exit(int status); -_Noreturn void _Exit(int status); +_Noreturn void _exit(int status); char *getenv(char const *name); diff --git a/sources/loader/config.c b/sources/loader/config.c index be65d4268..ac3d714d6 100644 --- a/sources/loader/config.c +++ b/sources/loader/config.c @@ -7,8 +7,8 @@ LoaderEntry config_entry_parse(Json json) { LoaderEntry entry; - entry.name = json_get(json, str$("name")).string; - entry.kernel = json_get(json, str$("kernel")).string; + entry.name = json_get(json, str$("name")).str; + entry.kernel = json_get(json, str$("kernel")).str; Json modules; if (json_try_get(json, str$("modules"), &modules)) @@ -20,8 +20,8 @@ LoaderEntry config_entry_parse(Json json) Json module = json_at(modules, i); LoaderModule current_module = {}; - current_module.name = json_get(module, str$("name")).string; - current_module.path = json_get(module, str$("path")).string; + current_module.name = json_get(module, str$("name")).str; + current_module.path = json_get(module, str$("path")).str; vec_push(&entry.modules, current_module); diff --git a/sources/protos/window.idl b/sources/protos/window.idl index 94d1c3d3a..faf302d51 100644 --- a/sources/protos/window.idl +++ b/sources/protos/window.idl @@ -8,6 +8,13 @@ type WindowClientProps = UiWinType type, }; +type WmLayout = enum +{ + WM_LAYOUT_STACK, + WM_LAYOUT_FIBONACCI, + WM_LAYOUT_MONOCLE, +}; + interface Client { method show -> Bool; diff --git a/sources/srvs/system/unit.c b/sources/srvs/system/unit.c index 11c9e893a..6a033e769 100644 --- a/sources/srvs/system/unit.c +++ b/sources/srvs/system/unit.c @@ -1,7 +1,8 @@ #include +#include #include #include -#include + #include "system/unit.h" void unit_init(Unit *self, Str name, BalMem payload, Alloc *alloc) @@ -23,7 +24,7 @@ void unit_init_from_module(Unit *self, HandoverModule mod, Alloc *alloc) Json manifest_json = json_parse_str(manifest_str, alloc); - Str unit_name = json_get(manifest_json, str$("name")).string; + Str unit_name = json_get(manifest_json, str$("name")).str; unit_init(self, unit_name, module_mem, alloc); @@ -39,11 +40,11 @@ void unit_init_from_module(Unit *self, HandoverModule mod, Alloc *alloc) for (int j = 0; j < json_len(rights); j++) { - BrRight right = br_right_from_str(json_at(rights, j).string); + BrRight right = br_right_from_str(json_at(rights, j).str); if (right == 0) { - log$("Invalid right: {}", json_at(rights, j).string); + log$("Invalid right: {}", json_at(rights, j).str); } self->rights |= right; diff --git a/sources/utils/cc/main.c b/sources/utils/cc/main.c index e75e3dcce..abacd1aaa 100644 --- a/sources/utils/cc/main.c +++ b/sources/utils/cc/main.c @@ -5,8 +5,166 @@ #include #include #include +#include #include +// FIXME: this will be moved in an other file later. +SrcFilePosInfo report_info(SrcRef ref, Str src) +{ + int begin = ref.begin; + int end = ref.end; + int line_len; + + int line_number_start = str_count_chr(str_sub(src, 0, begin), '\n') + 1; + int line_number_end = str_count_chr(str_sub(src, 0, end), '\n') + 1; + int line_start = str_last_chr(str_sub(src, 0, begin), '\n') + 1; + int line_end = str_first_chr(str_sub(src, end, src.len), '\n') + end; + bool is_multiline = line_number_start != line_number_end; + if (!is_multiline) + { + line_len = str_first_chr(str_sub(src, line_start, src.len), '\n'); + } + else + { + line_len = str_last_chr(str_sub(src, line_start, line_end + 1), '\n'); + } + + if (line_len == -1) + { + line_len = src.len; + } + + return (SrcFilePosInfo){ + .is_multiline = is_multiline, + .char_line_len = line_len, + .char_line_end = line_end, + .char_line_start = line_start, + .line_number_end = line_number_end, + .line_number_start = line_number_start, + }; +} + +void report_csema_line(Emit *out, Str src, SrcFilePosInfo info, bool only_first_line) +{ + Str line = str_sub(src, info.char_line_start, info.char_line_start + info.char_line_len); + emit_fmt$(out, "{3d fg-blue} {fg-blue} ", info.line_number_start, "|"); + + if (info.is_multiline && !only_first_line) + { + emit_fmt$(out, "{fg-red} ", "/"); + } + + int line_number = info.line_number_start; + for (int i = 0; i < info.char_line_len; i++) + { + if (line.buf[i] == '\n') + { + if (only_first_line) + { + break; + } + line_number++; + emit_fmt$(out, "\n{3d fg-blue} {fg-blue} ", line_number, "|"); + + if (info.is_multiline) + { + emit_fmt$(out, "{fg-red} ", "|"); + } + } + else + { + emit_fmt$(out, "{}", line.buf[i]); + } + } +} + +void report_csema_dump(ParseReport report, Emit *out, Scan *source, Str filename) +{ + SrcRef src_ref = report.info.ref; + int begin = src_ref.begin; + int end = src_ref.end; + + if (report.level == PARSE_WARN) + { + emit_fmt$(out, "\n! warn: {red}\n", report.info.msg); + } + else if (report.level == PARSE_ERR) + { + emit_fmt$(out, "\n!! {fg-red bold}({fg-red}): {bold}\n", "error", report.report_user_id, report.info.msg); + } + + Str src = str_n$(source->size, (char *)source->buf); + SrcFilePosInfo info = report_info(src_ref, src); + // number of line from begin + emit_fmt$(out, "-> {fg-blue}:{}:{} \n", filename, info.line_number_start, begin - info.char_line_start); + + report_csema_line(out, src, info, false); + + if (!info.is_multiline) + { + emit_fmt$(out, "\n : "); + + for (int i = info.char_line_start; i < info.char_line_len + info.char_line_start; i++) + { + if (i > begin && i <= end) + { + emit_fmt$(out, "{fg-red}", "^"); + } + else + { + emit_fmt$(out, " "); + } + } + emit_fmt$(out, " {fg-red}", report.info.msg); + } + + vec_foreach(v, &report.comments) + { + + bool is_comment_inline = v->ref.begin >= info.char_line_start && v->ref.end <= (info.char_line_len + info.char_line_start); + + if (!info.is_multiline && is_comment_inline) + { + emit_fmt$(out, "\n : "); + + for (int i = info.char_line_start; i < m_min(info.char_line_len + info.char_line_start, v->ref.end + 2); i++) + { + if (i > v->ref.begin && i <= v->ref.end) + { + emit_fmt$(out, "{fg-blue}", "-"); + } + else + { + emit_fmt$(out, " "); + } + } + } + else + { + emit_fmt$(out, "\n"); + SrcFilePosInfo info2 = report_info(v->ref, src); + report_csema_line(out, src, info2, true); + + emit_fmt$(out, "\n : "); + for (int i = info2.char_line_start; i < m_min(info2.char_line_len + info2.char_line_start, v->ref.end + 2); i++) + { + if (i > v->ref.begin && i <= v->ref.end) + { + emit_fmt$(out, "{fg-blue}", "-"); + } + else + { + emit_fmt$(out, " "); + } + } + emit_fmt$(out, " "); + } + emit_fmt$(out, "{fg-blue}", v->msg); + } + + emit_fmt$(out, "\n"); +} + int main(int argc, char const *argv[]) { if (argc < 2) @@ -29,7 +187,7 @@ int main(int argc, char const *argv[]) Scan scan; scan_init(&scan, buf_str(&source_buf)); - Lex unprocessed = clex(&scan, base$(&heap)); + Lex unprocessed = clex(&scan, base$(&heap), 0); Lex processed = cproc_file(&unprocessed, str$(argv[1]), base$(&heap)); if (scan_dump_error(&scan, io_chan_err())) @@ -39,11 +197,17 @@ int main(int argc, char const *argv[]) CUnit unit = cparse_unit(&processed, base$(&heap)); CSema sema; - csema_init(&sema, base$(&heap)); - unit = csema_unit(&sema, unit, base$(&heap)); + // csema_init(&sema, base$(&heap)); + + // unit = csema_unit(&sema, unit, base$(&heap)); + + // do_sema_checks(&unit, &sema); + Emit emit; emit_init(&emit, io_chan_out()); + parse_reports_dump(&sema.reports, &scan, &emit, str$(argv[1])); + emit_fmt$(&emit, "\n"); emit_fmt$(&emit, "--- BEGIN OG CODE ---\n"); @@ -65,7 +229,7 @@ int main(int argc, char const *argv[]) emit_ident_size(&emit, 4); emit_fmt$(&emit, "--- BEGIN CODE ---\n"); - cc_trans_unit(&emit, unit); + ctrans_unit(&emit, unit); emit_fmt$(&emit, "--- END CODE ---\n"); emit_fmt$(&emit, "\n"); diff --git a/sources/utils/fontinfo/main.c b/sources/utils/fontinfo/main.c index f462ad71d..21c3e04da 100644 --- a/sources/utils/fontinfo/main.c +++ b/sources/utils/fontinfo/main.c @@ -27,9 +27,9 @@ int main(int argc, char const *argv[]) vec_foreach(font, &ssfn_coll) { log$(""); - log$("[{}] Name: {}", idx, font->stringtable.font_name); - log$("[{}] Family: {}", idx, font->stringtable.family_name); - log$("[{}] Subfamily: {}", idx, font->stringtable.subfamily_name); + log$("[{}] Name: {}", idx, font->strtable.font_name); + log$("[{}] Family: {}", idx, font->strtable.family_name); + log$("[{}] Subfamily: {}", idx, font->strtable.subfamily_name); idx++; } diff --git a/sources/utils/idl/main.c b/sources/utils/idl/main.c index 5ebcdb2ae..409a89c12 100644 --- a/sources/utils/idl/main.c +++ b/sources/utils/idl/main.c @@ -56,12 +56,12 @@ int main(int argc, char const *argv[]) else if (str_eq(str$("--source"), str$(argv[2]))) { CUnit unit = idl_cgen_source(module, base$(&heap)); - cc_trans_unit(&emit, unit); + ctrans_unit(&emit, unit); } else if (str_eq(str$("--header"), str$(argv[2]))) { CUnit unit = idl_cgen_header(module, base$(&heap)); - cc_trans_unit(&emit, unit); + ctrans_unit(&emit, unit); } else { diff --git a/sources/utils/test/cc/cc.h b/sources/utils/test/cc/cc.h index a26d2b279..c06234e18 100644 --- a/sources/utils/test/cc/cc.h +++ b/sources/utils/test/cc/cc.h @@ -1,12 +1,22 @@ #pragma once -#include #include +#include // FIXME: get ride of thoses ugly macros. -#define ctx_lex(lexer_name, str) \ - Scan _scan = {}; \ - scan_init(&_scan, str); \ - Lex lexer_name = clex(&_scan, test_use_alloc()); \ +#define ctx_lex(lexer_name, str) \ + Scan _scan = {}; \ + scan_init(&_scan, str); \ + Lex lexer_name = clex(&_scan, test_alloc(), 0); \ scan_assert_no_error(&_scan) + +#define ctx_lex_proc(lexer_name, str) \ + Scan _scan = {}; \ + scan_init(&_scan, str); \ + Lex _source_lex = clex(&_scan, test_alloc(), 0); \ + scan_assert_no_error(&_scan); \ + Lex lexer_name = cproc_file(&_source_lex, str$("test.c"), test_alloc()); \ + lex_assert_no_error(&_source_lex) + +bool assert_lex_eq(Lex *first, Str left); diff --git a/sources/utils/test/json/json.c b/sources/utils/test/json/json.c index a701539d4..72ed808e3 100644 --- a/sources/utils/test/json/json.c +++ b/sources/utils/test/json/json.c @@ -11,7 +11,7 @@ test$(json_parse_test) Json res = json_get(json, str$("hello")); - expect_str_equal$(res.string, str$("world")); + assert_str_equal(res.str, str$("world")); } test$(json_parse_int) @@ -57,8 +57,8 @@ test$(json_parse_object_in_object) Json oh = json_get(res, str$("oh")); Json is = json_get(res, str$("is")); - expect_str_equal$(oh.string, str$("rust")); - expect_str_equal$(is.string, str$("based")); + assert_str_equal(oh.str, str$("rust")); + assert_str_equal(is.str, str$("based")); } test$(json_parse_table) @@ -72,10 +72,10 @@ test$(json_parse_table) expect_equal$(res.array.len, 4); - expect_str_equal$(res.array.data[0].string, str$("oh")); - expect_str_equal$(res.array.data[1].string, str$("rust")); - expect$(json_is(res.array.data[2], JSON_OBJECT)); - expect_str_equal$(res.array.data[3].string, str$("cool")); + assert_str_equal(res.array.data[0].str, str$("oh")); + assert_str_equal(res.array.data[1].str, str$("rust")); + assert_truth(json_is(res.array.data[2], JSON_OBJECT)); + assert_str_equal(res.array.data[3].str, str$("cool")); } test$(json_parse_comment_test) @@ -87,5 +87,5 @@ test$(json_parse_comment_test) Json res = json_get(json, str$("hello")); - expect_str_equal$(res.string, str$("world")); + assert_str_equal(res.str, str$("world")); }