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

Fix bugs found with the dijkstra example #191

Merged
merged 5 commits into from
Aug 24, 2022
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
3 changes: 2 additions & 1 deletion .run/Spice_run.run.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Spice_run" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -ir ../../media/test-project/os-test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="Spice_run" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="Spice_run">
<configuration default="false" name="Spice_run" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O2 -ir ../../media/test-project/os-test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="Spice_run" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="Spice_run">
<envs>
<env name="RUN_TESTS" value="OFF" />
<env name="SPICE_STD_DIR" value="$PROJECT_DIR$/std" />
</envs>
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
Expand Down
1 change: 1 addition & 0 deletions .run/Spice_test.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<configuration default="false" name="Spice_test" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="false" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="Spice_test" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="Spice_test">
<envs>
<env name="RUN_TESTS" value="ON" />
<env name="SPICE_STD_DIR" value="$PROJECT_DIR$/std" />
</envs>
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
Expand Down
122 changes: 70 additions & 52 deletions media/test-project/os-test.spice
Original file line number Diff line number Diff line change
Expand Up @@ -10,72 +10,90 @@ f<int> main() {
printf("Hello %s!", p1.getSecond());
}*/

import "std/type/int" as integer;
import "std/math/rand" as rand;

const int vertexCount = 9;
const int row = 10;
const int col = 10;
const int generationsToCalculate = 5;

f<int> minDistance(int[] dist, bool[] sptSet) {
int min = integer::MAX_VALUE;
int minIndex;
p rowLineTop() {
printf("\n");
for int i = 0; i < col; i++ { printf("╭─────╮"); }
printf("\n");
}

for int v = 0; v < vertexCount; v++ {
if !sptSet[v] && dist[v] <= min {
min = dist[v];
minIndex = v;
}
}
p rowLineMiddle() {
printf("\n");
for int i = 0; i < col; i++ { printf("├─────┤"); }
printf("\n");
}

return minIndex;
p rowLineBottom() {
printf("\n");
for int i = 0; i < col; i++ { printf("╰─────╯"); }
printf("\n");
}

p printSolution(int[] dist) {
printf("Vertex \t\t Distance from source\n");
for int i = 0; i < vertexCount; i++ {
printf("%d \t\t %d\n", i, dist[i]);
p printGeneration(string name, int[10][10] matrix) {
printf("%s:\n", name);
rowLineTop();
for int i = 0; i < row; i++ {
if i > 0 {
rowLineMiddle();
}
for int j = 0; j < col; j++ {
printf("│ %d │", matrix[i][j]);
}
}
rowLineBottom();
}

p dijkstra(int[vertexCount][vertexCount] graph, int src) {
int[vertexCount] dist;
bool[vertexCount] sptSet;

// Fill with default values
for int i = 0; i < vertexCount; i++ {
dist[i] = integer::MAX_VALUE;
sptSet[i] = false;
f<int> countLiveNeighborCell(int[10][10] matrix, int r, int c) {
int count = 0;
for int i = r - 1; i <= r + 1; i++ {
for int j = c - 1; j <= c + 1; j++ {
if (i == r && j == c) || (i < 0 || j < 0) || (i >= row || j >= col) {
continue;
}
if matrix[i][j] == 1 {
count++;
}
}
}
return count;
}

// Set distance to starting node to 0
dist[src] = 0;
f<int> main() {
int[10][10] a;
int[10][10] b;

for int count = 0; count < vertexCount - 1; count++ {
int u = minDistance(dist, sptSet);
sptSet[u] = true;
for int v = 0; v < vertexCount; v++ {
if (!sptSet[v] && graph[u][v] != 0 && dist[u] != integer::MAX_VALUE &&
dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
// Generate matrix canvas with random values (live and dead cells)
for int i = 0; i < row; i++ {
for int j = 0; j < col; j++ {
a[i][j] = rand.randInt(0, 1);
}
}
printGeneration("Initial state", a);

// Print the solution
printSolution(dist);
}
for int generation = 1; generation < generationsToCalculate; generation++ {
// Calculate next generation
for int i = 0; i < row; i++ {
for int j = 0; j < col; j++ {
int neighbor_live_cell = countLiveNeighborCell(a, i, j);
if a[i][j] == 1 && (neighbor_live_cell == 2 || neighbor_live_cell == 3) {
b[i][j] = 1;
} else if a[i][j] == 0 && neighbor_live_cell == 3 {
b[i][j] = 1;
} else {
b[i][j] = 0;
}
}
}

f<int> main() {
int[vertexCount][vertexCount] graph = {};
graph[0] = { 0, 4, 0, 0, 0, 0, 0, 8, 0 };
graph[1] = { 4, 0, 8, 0, 0, 0, 0, 11, 0 };
graph[2] = { 0, 8, 0, 7, 0, 4, 0, 0, 2 };
graph[3] = { 0, 0, 7, 0, 9, 14, 0, 0, 0 };
graph[4] = { 0, 0, 0, 9, 0, 10, 0, 0, 0 };
graph[5] = { 0, 0, 4, 14, 10, 0, 2, 0, 0 };
graph[6] = { 0, 0, 0, 0, 0, 2, 0, 1, 6 };
graph[7] = { 8, 11, 0, 0, 0, 0, 1, 0, 7 };
graph[8] = { 0, 0, 2, 0, 0, 0, 6, 7, 0 };
// Print next generation
printGeneration("\nNext generation", b);

printf("Computing shortest paths with Dijkstra's algorithm ...\n");
dijkstra(graph, 0);
printf("Done.\n");
}
// Set new matrix to old matrix
a = b;
}
}
13 changes: 7 additions & 6 deletions src/analyzer/PreAnalyzerVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ std::any PreAnalyzerVisitor::visitImportStmt(ImportStmtNode *node) {
std::string stdPath;
if (FileUtil::fileExists("/usr/lib/spice/std")) {
stdPath = "/usr/lib/spice/std/";
} else if (FileUtil::dirExists(std::string(std::getenv("SPICE_STD_DIR")))) {
} else if (std::getenv("SPICE_STD_DIR") && FileUtil::dirExists(std::string(std::getenv("SPICE_STD_DIR")))) {
stdPath = std::string(std::getenv("SPICE_STD_DIR"));
if (stdPath.rfind(FileUtil::DIR_SEPARATOR) != stdPath.size() - 1)
stdPath += FileUtil::DIR_SEPARATOR;
} else {
throw err.get(node->codeLoc, STD_NOT_FOUND,
"Standard library could not be found. Check if the env var SPICE_STD_DIR exists");
throw ErrorFactory::get(node->codeLoc, STD_NOT_FOUND,
"Standard library could not be found. Check if the env var SPICE_STD_DIR exists");
}
// Check if source file exists
std::string defaultPath = stdPath + sourceFileIden + ".spice";
Expand All @@ -50,8 +50,8 @@ std::any PreAnalyzerVisitor::visitImportStmt(ImportStmtNode *node) {
} else if (FileUtil::fileExists(osArchPath)) {
importPath = osArchPath;
} else {
throw err.get(node->codeLoc, IMPORTED_FILE_NOT_EXISTING,
"The source file '" + node->importPath + ".spice' was not found in the standard library");
throw ErrorFactory::get(node->codeLoc, IMPORTED_FILE_NOT_EXISTING,
"The source file '" + node->importPath + ".spice' was not found in the standard library");
}
} else { // Include own source file
// Check in module registry if the file can be imported
Expand All @@ -69,7 +69,8 @@ std::any PreAnalyzerVisitor::visitImportStmt(ImportStmtNode *node) {
} else if (FileUtil::fileExists(osArchPath)) {
importPath = osArchPath;
} else {
throw err.get(node->codeLoc, IMPORTED_FILE_NOT_EXISTING, "The source file '" + node->importPath + ".spice' does not exist");
throw ErrorFactory::get(node->codeLoc, IMPORTED_FILE_NOT_EXISTING,
"The source file '" + node->importPath + ".spice' does not exist");
}
}
CommonUtil::replaceAll(importPath, "/", std::string(1, FileUtil::DIR_SEPARATOR));
Expand Down
21 changes: 18 additions & 3 deletions src/generator/GeneratorVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2316,7 +2316,17 @@ std::any GeneratorVisitor::visitAtomicExpr(AtomicExprNode *node) {
// Initialize if it is an external global var
if (importedScope)
entry = initExtGlobal(node->identifier, scopePath.getScopePrefix(true) + node->identifier);
return entry->getAddress();

// Return the address if modifiable
if (!entry->getSpecifiers().isConst())
return entry->getAddress();

// Save value of global to a new address to get it modifiable
llvm::Type *globalTy = entry->getType().toLLVMType(*context, accessScope);
llvm::Value *globalValue = builder->CreateLoad(globalTy, entry->getAddress());
llvm::Value *memoryAddress = insertAlloca(globalTy);
builder->CreateStore(globalValue, memoryAddress);
return memoryAddress;
}

// Struct or Struct* or Struct** or ...
Expand Down Expand Up @@ -2618,7 +2628,12 @@ std::any GeneratorVisitor::visitFunctionCall(FunctionCallNode *node) {
// Get the actual arg value
SymbolType actualArgSymbolType = arg->getEvaluatedSymbolType();
llvm::Value *actualArgPtr = resolveAddress(arg);
if (actualArgSymbolType == expectedArgSymbolType) {

// If the arrays are both of size -1 or 0, they are both pointers and do not need to be implicitly casted
bool isSameArray = actualArgSymbolType.isArray() && expectedArgSymbolType.isArray() &&
actualArgSymbolType.getArraySize() <= 0 && expectedArgSymbolType.getArraySize() <= 0;

if (actualArgSymbolType == expectedArgSymbolType || isSameArray) {
actualArgPtr = builder->CreateLoad(actualArgSymbolType.toLLVMType(*context, accessScope), actualArgPtr);
} else {
actualArgPtr = doImplicitCast(actualArgPtr, expectedArgType, actualArgSymbolType);
Expand Down Expand Up @@ -2690,7 +2705,7 @@ std::any GeneratorVisitor::visitArrayInitialization(ArrayInitializationNode *nod

// Visit all args to check if they are hardcoded or not
allArgsHardcoded = true;
for (size_t i = 0; i < std::min(node->itemLst()->args().size(), arraySize); i++) {
for (size_t i = 0; i < std::min(actualItemCount, arraySize); i++) {
currentConstValue = nullptr;
lhsVarName = lhsVarNameBackup + "." + std::to_string(i);

Expand Down
8 changes: 6 additions & 2 deletions src/parser/AstBuilderVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,8 @@ std::any AstBuilderVisitor::visitBreakStmt(SpiceParser::BreakStmtContext *ctx) {
auto breakStmtNode = dynamic_cast<BreakStmtNode *>(currentNode);

// Extract number of breaks
breakStmtNode->breakTimes = std::stoi(ctx->INT_LIT()->toString());
if (ctx->INT_LIT())
breakStmtNode->breakTimes = std::stoi(ctx->INT_LIT()->toString());

return nullptr;
}
Expand All @@ -698,7 +699,8 @@ std::any AstBuilderVisitor::visitContinueStmt(SpiceParser::ContinueStmtContext *
auto continueStmtNode = dynamic_cast<ContinueStmtNode *>(currentNode);

// Extract number of continues
continueStmtNode->continueTimes = std::stoi(ctx->INT_LIT()->toString());
if (ctx->INT_LIT())
continueStmtNode->continueTimes = std::stoi(ctx->INT_LIT()->toString());

return nullptr;
}
Expand Down Expand Up @@ -1057,6 +1059,8 @@ std::any AstBuilderVisitor::visitMultiplicativeExpr(SpiceParser::MultiplicativeE
multiplicativeExprNode->opQueue.emplace(MultiplicativeExprNode::OP_MUL, SymbolType(TY_INVALID));
else if (auto t = dynamic_cast<antlr4::tree::TerminalNode *>(subTree); t->getSymbol()->getType() == SpiceParser::DIV)
multiplicativeExprNode->opQueue.emplace(MultiplicativeExprNode::OP_DIV, SymbolType(TY_INVALID));
else if (auto t = dynamic_cast<antlr4::tree::TerminalNode *>(subTree); t->getSymbol()->getType() == SpiceParser::REM)
multiplicativeExprNode->opQueue.emplace(MultiplicativeExprNode::OP_REM, SymbolType(TY_INVALID));
else
assert(dynamic_cast<antlr4::tree::TerminalNode *>(subTree)); // Fail if we did not get a terminal

Expand Down
4 changes: 2 additions & 2 deletions std/type/int.spice
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public f<bool> toBool(int input) {
}

// Helper function: returns the string of a small number
f<string> small(int i) {
/*f<string> small(int i) {
if i < 10 {
return smallsString10.substring(i, i+1);
}
return smallsString100.substring(i*2, i*2+2);
}
}*/
19 changes: 11 additions & 8 deletions test/StdTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,17 @@ void executeStdTest(const TestCase &testCase) {

// Test classes
class StdDataTests : public ::testing::TestWithParam<TestCase> {};
class StdExamplesTests : public ::testing::TestWithParam<TestCase> {};
class StdIOTests : public ::testing::TestWithParam<TestCase> {};
class StdOSTests : public ::testing::TestWithParam<TestCase> {};
class StdTextTests : public ::testing::TestWithParam<TestCase> {};

// Test macros
TEST_P(StdDataTests, DataTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdIOTests, IOTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdOSTests, OSTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdTextTests, TextTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdDataTests, DataTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdExamplesTests, ExamplesTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdIOTests, IOTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdOSTests, OSTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)
TEST_P(StdTextTests, TextTests) { executeStdTest(GetParam()); } // NOLINT(cert-err58-cpp)

// Name resolver
struct NameResolver {
Expand All @@ -305,9 +307,10 @@ struct NameResolver {
// Instantiations
const std::vector<TestSuite> testSuites = detectStdTestSuites(); // NOLINT(cert-err58-cpp)

INSTANTIATE_TEST_SUITE_P(, StdDataTests, ::testing::ValuesIn(testSuites[0]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdIOTests, ::testing::ValuesIn(testSuites[1]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdOSTests, ::testing::ValuesIn(testSuites[2]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdTextTests, ::testing::ValuesIn(testSuites[3]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdDataTests, ::testing::ValuesIn(testSuites[0]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdExamplesTests, ::testing::ValuesIn(testSuites[1]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdIOTests, ::testing::ValuesIn(testSuites[2]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdOSTests, ::testing::ValuesIn(testSuites[3]), NameResolver()); // NOLINT(cert-err58-cpp)
INSTANTIATE_TEST_SUITE_P(, StdTextTests, ::testing::ValuesIn(testSuites[4]), NameResolver()); // NOLINT(cert-err58-cpp)

// GCOV_EXCL_STOP
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [36 x i8] c"Ackermann of base m=%d and n=%d: %d\00", align 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [36 x i8] c"Ackermann of base m=%d and n=%d: %d\00", align 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [21 x i8] c"Faculty of %d is: %d\00", align 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [21 x i8] c"Faculty of %d is: %d\00", align 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [33 x i8] c"Thread returned with result: %d\0A\00", align 1
@1 = private unnamed_addr constant [17 x i8] c"Program finished\00", align 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [20 x i8] c"Fibonacci of %d: %d\00", align 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; ModuleID = 'source.spice'
source_filename = "source.spice"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-w64-windows-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@0 = private unnamed_addr constant [20 x i8] c"Fibonacci of %d: %d\00", align 1

Expand Down
Loading