diff options
Diffstat (limited to 'source/symbol.elna')
| -rw-r--r-- | source/symbol.elna | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/source/symbol.elna b/source/symbol.elna new file mode 100644 index 0000000..531f58c --- /dev/null +++ b/source/symbol.elna @@ -0,0 +1,200 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. *) +module +import cstdlib, common, ast + +type + ElnaSymbolInfoKind* = (type_info, temporary_info, procedure_info) + ElnaSymbolInfo* = record + kind: ElnaSymbolInfoKind + end + ElnaSymbolTypeInfo* = record(ElnaSymbolInfo) + _type: ^ElnaType + end + ElnaSymbolTemporaryInfo* = record(ElnaSymbolInfo) + attr: Word; + variable_type: ^ElnaType + end + ElnaSymbolProcedureInfo* = record(ElnaSymbolInfo) + symbol_table: ^ElnaSymbolTable; + procedure_type: ^ElnaTypeProcedure; + is_extern: Bool + end + + ElnaSymbolEntry* = record + name: []const Word8; + symbol_info: ^ElnaSymbolInfo + end + ElnaSymbolTable* = record + count: Word; + capacity: Word; + parent: ^ElnaSymbolTable; + symbols: ^ElnaSymbolEntry + end + +var + symbol_table_global*: ^ElnaSymbolTable + word_type*: ^ElnaType + int_type*: ^ElnaType + pointer_type*: ^ElnaType + bool_type*: ^ElnaType + char_type*: ^ElnaType + string_type*: ^ElnaTypeRecord + +proc elna_symbol_type_info_create*(type_representation: ^ElnaType) -> ^ElnaSymbolTypeInfo +var + result: ^ElnaSymbolTypeInfo +begin + result := malloc#[ElnaSymbolTypeInfo](#size(ElnaSymbolTypeInfo)); + result^.kind := ElnaSymbolInfoKind.type_info; + result^._type := type_representation +return result + +proc elna_symbol_temporary_info_create*(attr: Word; temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo +var + result: ^ElnaSymbolTemporaryInfo +begin + result := malloc#[ElnaSymbolTemporaryInfo](#size(ElnaSymbolTemporaryInfo)); + result^.kind := ElnaSymbolInfoKind.temporary_info; + result^.variable_type := temporary_type; + result^.attr := attr +return result + +proc elna_symbol_procedure_info_create*(is_extern: Bool) -> ^ElnaSymbolProcedureInfo +var + result: ^ElnaSymbolProcedureInfo +begin + result := malloc#[ElnaSymbolProcedureInfo](#size(ElnaSymbolProcedureInfo)); + result^.kind := ElnaSymbolInfoKind.procedure_info; + result^.procedure_type := nil; + result^.symbol_table := nil; + result^.is_extern := is_extern +return result + +proc elna_symbol_table_create*(parent: ^ElnaSymbolTable) -> ^ElnaSymbolTable +var + new_symbol_table: ^ElnaSymbolTable +begin + new_symbol_table := malloc#[ElnaSymbolTable](#size(ElnaSymbolTable)); + new_symbol_table^.capacity := 64u; + new_symbol_table^.symbols := malloc#[ElnaSymbolEntry](new_symbol_table^.capacity * #size(ElnaSymbolEntry)); + new_symbol_table^.count := 0u; + new_symbol_table^.parent := parent +return new_symbol_table + +proc elna_symbol_table_enter*(symbol_table: ^ElnaSymbolTable; symbol_name: []const Word8; symbol: ^ElnaSymbolInfo) +var + entry: ^ElnaSymbolEntry +begin + if symbol_table^.count >= symbol_table^.capacity then + symbol_table^.capacity := symbol_table^.capacity * 2u; + symbol_table^.symbols := realloc#[ElnaSymbolEntry](symbol_table^.symbols, symbol_table^.capacity * #size(ElnaSymbolEntry)) + end; + entry := symbol_table^.symbols + symbol_table^.count; + entry^.name := symbol_name; + entry^.symbol_info := symbol; + symbol_table^.count := symbol_table^.count + 1u +return + +proc elna_symbol_table_lookup_local*(symbol_table: ^ElnaSymbolTable; symbol_name: []const Word8) -> ^ElnaSymbolInfo +var + i: Word := 0u + entry: ^ElnaSymbolEntry + result: ^ElnaSymbolInfo := nil +begin + while i < symbol_table^.count & result = nil do + entry := symbol_table^.symbols + i; + if entry^.name = symbol_name then + result := entry^.symbol_info + end; + i := i + 1u + end +return result + +proc elna_symbol_table_lookup*(symbol_table: ^ElnaSymbolTable; symbol_name: []const Word8) -> ^ElnaSymbolInfo +var + current: ^ElnaSymbolTable + found: ^ElnaSymbolInfo := nil +begin + current := symbol_table; + while current <> nil & found = nil do + found := elna_symbol_table_lookup_local(current, symbol_name); + current := current^.parent + end +return found + +proc elna_symbol_string_build() +var + current_field: ^ElnaTypeField + char_pointer: ^ElnaTypePointer +begin + string_type := malloc#[ElnaTypeRecord](#size(ElnaTypeRecord)); + string_type^.kind := ElnaTypeKind._record; + string_type^.size := 16u; + string_type^.alignment := 8u; + string_type^.members := malloc#[ElnaTypeField](2u * #size(ElnaTypeField)); + string_type^.length := 2u; + + char_pointer := malloc#[ElnaTypePointer](#size(ElnaTypePointer)); + char_pointer^.kind := ElnaTypeKind.pointer; + char_pointer^.size := 8u; + char_pointer^.alignment := 8u; + char_pointer^.base := char_type; + + current_field := string_type^.members; + current_field^.name := "ptr"; + current_field^.field_type := cast(char_pointer: ^ElnaType); + + current_field := current_field + 1u; + current_field^.name := "length"; + current_field^.field_type := word_type +return + +proc elna_symbol_table_build*() +var + current_info: ^ElnaSymbolTypeInfo +begin + symbol_table_global := elna_symbol_table_create(nil); + + word_type := malloc#[ElnaType](#size(ElnaType)); + word_type^.kind := ElnaTypeKind.primitive; + word_type^.size := 8u; + word_type^.alignment := 8u; + current_info := elna_symbol_type_info_create(word_type); + elna_symbol_table_enter(symbol_table_global, "Word", cast(current_info: ^ElnaSymbolInfo)); + + int_type := malloc#[ElnaType](#size(ElnaType)); + int_type^.kind := ElnaTypeKind.primitive; + int_type^.size := 8u; + int_type^.alignment := 8u; + current_info := elna_symbol_type_info_create(int_type); + elna_symbol_table_enter(symbol_table_global, "Int", cast(current_info: ^ElnaSymbolInfo)); + + pointer_type := malloc#[ElnaType](#size(ElnaType)); + pointer_type^.kind := ElnaTypeKind.primitive; + pointer_type^.size := 8u; + pointer_type^.alignment := 8u; + current_info := elna_symbol_type_info_create(pointer_type); + elna_symbol_table_enter(symbol_table_global, "Pointer", cast(current_info: ^ElnaSymbolInfo)); + + bool_type := malloc#[ElnaType](#size(ElnaType)); + bool_type^.kind := ElnaTypeKind.primitive; + bool_type^.size := 1u; + bool_type^.alignment := 1u; + current_info := elna_symbol_type_info_create(bool_type); + elna_symbol_table_enter(symbol_table_global, "Bool", cast(current_info: ^ElnaSymbolInfo)); + + char_type := malloc#[ElnaType](#size(ElnaType)); + char_type^.kind := ElnaTypeKind.primitive; + char_type^.size := 1u; + char_type^.alignment := 1u; + current_info := elna_symbol_type_info_create(char_type); + elna_symbol_table_enter(symbol_table_global, "Char", cast(current_info: ^ElnaSymbolInfo)); + + elna_symbol_string_build(); + current_info := elna_symbol_type_info_create(cast(string_type: ^ElnaType)); + elna_symbol_table_enter(symbol_table_global, "String", cast(current_info: ^ElnaSymbolInfo)) +return + +end. |
