Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish map std #442

Merged
merged 17 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .run/spice.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -d -ir ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O0 -d -ir -g ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_LIB_DIR" value="D:/LLVM/build-release/lib" />
<env name="LLVM_INCLUDE_DIR" value="D:/LLVM/llvm/include" />
Expand Down
2 changes: 1 addition & 1 deletion .run/spicetest.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spicetest" type="CMakeGoogleTestRunConfigurationType" factoryName="Google Test" PROGRAM_PARAMS="--update-refs=true" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spicetest" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spicetest" TEST_MODE="SUITE_TEST">
<configuration default="false" name="spicetest" type="CMakeGoogleTestRunConfigurationType" factoryName="Google Test" PROGRAM_PARAMS="--update-refs=false" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spicetest" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spicetest" TEST_MODE="SUITE_TEST">
<envs>
<env name="RUN_TESTS" value="ON" />
<env name="SPICE_STD_DIR" value="$PROJECT_DIR$/std" />
Expand Down
74 changes: 47 additions & 27 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,31 +1,51 @@
import "std/io/cli-parser";
import "std/data/map";

type CliOptions struct {
bool sayHi = false
}

p callback(bool& value) {
printf("Callback called with value %d\n", value);
}

f<int> main(int argc, string[] argv) {
CliParser parser = CliParser("Test Program", "This is a simple test program");
parser.setVersion("v0.1.0");
parser.setFooter("Copyright (c) Marc Auberer 2021-2024");

CliOptions options;
parser.addFlag("--hi", options.sayHi, "Say hi to the user");
parser.addFlag("--callback", callback, "Call a callback function");
parser.addFlag("-cb", p(bool& value) {
printf("CB called with value %d\n", value);
}, "Call a callback function");

parser.parse(argc, argv);

// Print hi if requested
if options.sayHi {
printf("Hi!\n");
}
f<int> main() {
Map<int, string> map;
assert map.getSize() == 0l;
assert map.isEmpty();
map.insert(1, "Hello");
assert map.getSize() == 1l;
assert !map.isEmpty();
map.insert(2, "World");
assert map.getSize() == 2l;
map.insert(3, "Foo");
assert map.getSize() == 3l;
map.insert(4, "Bar");
assert map.getSize() == 4l;
assert map.contains(1);
assert map.contains(2);
assert map.contains(3);
assert map.contains(4);
assert map.get(1) == "Hello";
assert map.get(2) == "World";
assert map.get(3) == "Foo";
assert map.get(4) == "Bar";
map.remove(2);
assert map.getSize() == 3l;
assert !map.contains(2);
assert !map.isEmpty();
map.remove(1);
assert map.getSize() == 2l;
assert !map.contains(1);
assert !map.isEmpty();
string& foo = map.get(3);
assert foo == "Foo";
foo = "Baz";
assert map.get(3) == "Baz";
Result<string> bar = map.getSafe(4);
assert bar.isOk();
assert bar.unwrap() == "Bar";
Result<string> baz = map.getSafe(5);
assert baz.isErr();
map.remove(3);
assert map.getSize() == 1l;
assert !map.contains(3);
assert !map.isEmpty();
map.remove(4);
assert map.getSize() == 0l;
assert !map.contains(4);
assert map.isEmpty();
}

/*import "../../src-bootstrap/lexer/lexer";
Expand Down
11 changes: 8 additions & 3 deletions media/test-project/test2.spice
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import "test3" as s2;
type A dyn;

p test() {
printf("p: %f", s2.getDouble());
public p printFormat<A>(A element) {
printf("Sizeof output: %d\n", sizeof(element));
}

public f<A*> getAInc<A>(A* number) {
(*number)++;
return number;
}
10 changes: 7 additions & 3 deletions src/SourceFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,13 @@ void SourceFile::collectAndPrintWarnings() { // NOLINT(misc-no-recursion)
warning.print();
}

bool SourceFile::isStringRT() const { return globalScope->lookupStrict(STROBJ_NAME) != nullptr; }

bool SourceFile::isRttiRT() const { return globalScope->lookupStrict(TIOBJ_NAME) != nullptr; }
bool SourceFile::isRT(RuntimeModule runtimeModule) const {
assert(IDENTIFYING_TOP_LEVEL_NAMES.contains(runtimeModule));
const char *topLevelName = IDENTIFYING_TOP_LEVEL_NAMES.at(runtimeModule);
if (!exportedNameRegistry.contains(topLevelName))
return false;
return exportedNameRegistry.at(topLevelName).targetEntry->scope == globalScope.get();
}

bool SourceFile::haveAllDependantsBeenTypeChecked() const {
return std::ranges::all_of(dependants, [](const SourceFile *dependant) { return dependant->totalTypeCheckerRuns >= 1; });
Expand Down
5 changes: 3 additions & 2 deletions src/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ class SourceFile {
[[nodiscard]] const NameRegistryEntry *getNameRegistryEntry(const std::string &symbolName) const;
void checkForSoftErrors();
void collectAndPrintWarnings();
bool isStringRT() const;
bool isRttiRT() const;
bool isRT(RuntimeModule runtimeModule) const;
ALWAYS_INLINE bool isStringRT() const { return isRT(STRING_RT); }
ALWAYS_INLINE bool isRttiRT() const { return isRT(RTTI_RT); }

// Public fields
std::string name;
Expand Down
2 changes: 0 additions & 2 deletions src/exception/SemanticError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ std::string SemanticError::getMessagePrefix(SemanticErrorType type) {
return "Temporary bound to non-const reference";
case GENERIC_TYPE_NOT_IN_TEMPLATE:
return "Generic type not contained in template";
case GENERIC_TYPE_NOT_USED:
return "Template types not used";
case SPECIFIER_AT_ILLEGAL_CONTEXT:
return "Specifier at illegal context";
case INSUFFICIENT_VISIBILITY:
Expand Down
1 change: 0 additions & 1 deletion src/exception/SemanticError.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ enum SemanticErrorType : uint8_t {
REFERENCE_WITHOUT_INITIALIZER,
TEMP_TO_NON_CONST_REF,
GENERIC_TYPE_NOT_IN_TEMPLATE,
GENERIC_TYPE_NOT_USED,
SPECIFIER_AT_ILLEGAL_CONTEXT,
INSUFFICIENT_VISIBILITY,
JOIN_ARG_MUST_BE_TID,
Expand Down
18 changes: 18 additions & 0 deletions src/global/RuntimeModuleManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <cstdint>
#include <unordered_map>

#include <symboltablebuilder/SymbolType.h>

namespace spice::compiler {

// Forward declaration
Expand All @@ -22,6 +24,22 @@ enum RuntimeModule : uint8_t {
RTTI_RT = 1 << 2,
};

const std::unordered_map<const char *, RuntimeModule> TYPE_NAME_TO_RT_MODULE_MAPPING = {
{STROBJ_NAME, STRING_RT},
};

const std::unordered_map<const char *, RuntimeModule> FCT_NAME_TO_RT_MODULE_MAPPING = {
{"sAlloc", MEMORY_RT}, {"sRealloc", MEMORY_RT}, {"sCopy", MEMORY_RT}, {"sDealloc", MEMORY_RT},
{"sNew", MEMORY_RT}, {"sPlacementNew", MEMORY_RT}, {"sDelete", MEMORY_RT},
};

// This serves for the compiler to detect if a source file is a specific runtime module
const std::unordered_map<RuntimeModule, const char *> IDENTIFYING_TOP_LEVEL_NAMES = {
{STRING_RT, STROBJ_NAME}, // String struct
{MEMORY_RT, "sAlloc"}, // sAlloc function
{RTTI_RT, TIOBJ_NAME}, // TypeInfo struct
};

struct ModuleNamePair {
const char *const importName;
const char *const fileName;
Expand Down
2 changes: 1 addition & 1 deletion src/irgenerator/DebugInfoGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void DebugInfoGenerator::initialize(const std::string &sourceFileName, std::file
sourceFileDir.make_preferred();
llvm::DIFile *cuDiFile = diBuilder->createFile(absolutePath.string(), sourceFileDir.string());
compileUnit = diBuilder->createCompileUnit(
llvm::dwarf::DW_LANG_C_plus_plus_20, cuDiFile, producerString, irGenerator->cliOptions.optLevel > OptLevel::O0, "", 0, "",
llvm::dwarf::DW_LANG_C_plus_plus_14, cuDiFile, producerString, irGenerator->cliOptions.optLevel > OptLevel::O0, "", 0, "",
llvm::DICompileUnit::FullDebug, 0, false, false, llvm::DICompileUnit::DebugNameTableKind::None);

module->addModuleFlag(llvm::Module::Max, "Dwarf Version", llvm::dwarf::DWARF_VERSION);
Expand Down
5 changes: 5 additions & 0 deletions src/irgenerator/GenControlStructures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ std::any IRGenerator::visitForeachLoop(const ForeachLoopNode *node) {
// Resolve address of iterator
LLVMExprResult callResult = {.value = iterator, .node = iteratorAssignNode};
iteratorPtr = resolveAddress(callResult);

// Attach address to anonymous symbol to keep track of deallocation
SymbolTableEntry *returnSymbol = currentScope->symbolTable.lookupAnonymous(iteratorAssignNode->codeLoc);
assert(returnSymbol != nullptr);
returnSymbol->updateAddress(iteratorPtr);
} else { // The iteratorAssignExpr is of type Iterator
iteratorPtr = resolveAddress(iteratorAssignNode);
}
Expand Down
2 changes: 1 addition & 1 deletion src/irgenerator/GenImplicit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void IRGenerator::generateCtorOrDtorCall(SymbolTableEntry *entry, const Function
void IRGenerator::generateDeallocCall(llvm::Value *variableAddress) const {
// In case of string runtime, call free manually. Otherwise, use the memory_rt implementation of sDealloc()
if (sourceFile->isStringRT()) {
llvm::Function *freeFct = stdFunctionManager.getFreeFctPtr();
llvm::Function *freeFct = stdFunctionManager.getFreeFct();
builder.CreateCall(freeFct, variableAddress);
} else {
llvm::Function *deallocFct = stdFunctionManager.getDeallocBytePtrRefFct();
Expand Down
3 changes: 3 additions & 0 deletions src/irgenerator/IRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ llvm::Constant *IRGenerator::getConst(const CompileTimeValue &compileTimeValue,
if (type.is(TY_BOOL))
return builder.getInt1(compileTimeValue.boolValue);

if (type.is(TY_PTR))
return llvm::Constant::getNullValue(builder.getPtrTy());

throw CompilerError(UNHANDLED_BRANCH, "Constant fall-through"); // GCOV_EXCL_LINE
}

Expand Down
Loading