Skip to content

Commit

Permalink
Fix bugs and extend string runtime (#209)
Browse files Browse the repository at this point in the history
* Fix bug and extend http std

* Fix bug & extend string runtime

* Enable ccache for CI

* Fix bug in test runner
  • Loading branch information
marcauberer authored Oct 8, 2022
1 parent b30cc33 commit 20be089
Show file tree
Hide file tree
Showing 32 changed files with 445 additions and 222 deletions.
12 changes: 8 additions & 4 deletions .github/workflows/ci-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
- name: Setup Mold
uses: rui314/setup-mold@v1

- name: Setup CCache
uses: hendrikmuhs/ccache-action@v1

- name: Setup Gcovr
run: sudo pip install gcovr

Expand All @@ -53,8 +56,8 @@ jobs:
git clone --depth 1 --branch llvmorg-15.0.2 https://github.com/llvm/llvm-project llvm
mkdir ./llvm/build
cd ./llvm/build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS_RELEASE="-O2" -GNinja ../llvm
cmake --build .
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS_RELEASE="-O2" -GNinja ../llvm
cmake --build . -j$(nproc)
- name: Download Libs
run: |
Expand All @@ -65,10 +68,11 @@ jobs:
env:
LLVM_DIR: /home/runner/work/spice/llvm/build/lib/cmake/llvm
run: |
echo "/usr/lib/ccache:/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
mkdir ./bin
cd ./bin
cmake -DCMAKE_BUILD_TYPE=Debug -DSPICE_IS_GH_ACTIONS=ON -DSPICE_BUILT_BY="ghactions" -DSPICE_LINK_STATIC=OFF -DSPICE_DEV_COMPILE=ON -DSPICE_RUN_COVERAGE=ON -GNinja -Wattributes ..
cmake --build . --target Spice_test
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DSPICE_IS_GH_ACTIONS=ON -DSPICE_BUILT_BY="ghactions" -DSPICE_LINK_STATIC=OFF -DSPICE_DEV_COMPILE=ON -DSPICE_RUN_COVERAGE=ON -GNinja -Wattributes ..
cmake --build . --target Spice_test -j$(nproc)
- name: Run Test target
env:
Expand Down
13 changes: 9 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ jobs:
- name: Setup Mold
uses: rui314/setup-mold@v1

- name: Setup CCache
uses: hendrikmuhs/ccache-action@v1

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
Expand All @@ -46,12 +49,13 @@ jobs:
- name: Setup LLVM
if: steps.cache-llvm.outputs.cache-hit != 'true'
run: |
echo "/usr/lib/ccache:/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
cd ..
git clone --depth 1 --branch llvmorg-15.0.2 https://github.com/llvm/llvm-project llvm
mkdir ./llvm/build
cd ./llvm/build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS_RELEASE="-O2" -GNinja ../llvm
cmake --build .
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS_RELEASE="-O2" -GNinja ../llvm
cmake --build . -j$(nproc)
- name: Download Libs
run: |
Expand All @@ -62,10 +66,11 @@ jobs:
env:
LLVM_DIR: /home/runner/work/spice/llvm/build/lib/cmake/llvm
run: |
echo "/usr/lib/ccache:/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
mkdir ./bin
cd ./bin
cmake -DCMAKE_BUILD_TYPE=Release -DSPICE_BUILT_BY="ghactions" -DSPICE_LINK_STATIC=OFF -DSPICE_DEV_COMPILE=ON -GNinja -Wattributes ..
cmake --build . --target Spice_test
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DSPICE_BUILT_BY="ghactions" -DSPICE_LINK_STATIC=OFF -DSPICE_DEV_COMPILE=ON -GNinja -Wattributes ..
cmake --build . --target Spice_test -j$(nproc)
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
15 changes: 5 additions & 10 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,7 @@ jobs:
mkdir ./llvm/build
cd ./llvm/build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS_RELEASE="-O2" -GNinja -Wno-dev -Wattributes ../llvm
- name: Setup LLVM - Build
if: steps.cache-llvm.outputs.cache-hit != 'true'
run: |
cd ./llvm/build
cmake --build .
cmake --build . -j$(nproc)
- name: Download Libs
run: |
Expand All @@ -72,7 +67,7 @@ jobs:
mkdir ./bin
cd ./bin
cmake -GNinja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSPICE_LINK_STATIC=OFF -DSPICE_VERSION="${{ steps.get_version.outputs.version }}" -DSPICE_BUILT_BY="ghactions" -DCMAKE_CXX_FLAGS_RELEASE="-O2" ..
cmake --build . --target Spice_run
cmake --build . --target Spice_run -j$(nproc)
- name: Process build output
working-directory: bin
Expand Down Expand Up @@ -136,7 +131,7 @@ jobs:
mkdir ./llvm/build
cd ./llvm/build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS_RELEASE="-O2" -GNinja -Wno-dev -Wattributes ../llvm
cmake --build .
cmake --build . -j$(nproc)
- name: Download Libs
run: .\setup-libs.bat
Expand All @@ -151,7 +146,7 @@ jobs:
mkdir ./bin
cd ./bin
cmake -GNinja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DSPICE_LINK_STATIC=ON -DSPICE_VERSION="${{ steps.get_version.outputs.version }}" -DSPICE_BUILT_BY="ghactions" -DCMAKE_CXX_FLAGS_RELEASE="-O2" ..
cmake --build . --target Spice_run
cmake --build . --target Spice_run -j$(nproc)
- name: Process build output
working-directory: bin
Expand Down Expand Up @@ -359,4 +354,4 @@ jobs:
identifier: ChilliBits.Spice
version: ${{ github.ref_name }}
release-tag: ${{ github.ref_name }}
token: ${{ secrets.CR_PAT }}
token: ${{ secrets.CR_PAT }}
56 changes: 33 additions & 23 deletions media/test-project/os-test.spice
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
const int SIZE = 9;

p print(int[][] grid) {
for int i = 0; i < size; i++ {
for int j = 0; j < size; j++ {
printf("%d ", grid[i][j]);
}
printf("\n");
}
}
import "std/runtime/string_rt" as _rt_str;

f<int> main() {
int[SIZE][SIZE] grid = {
{ 3, 0, 6, 5, 0, 8, 4, 0, 0 },
{ 5, 2, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 8, 7, 0, 0, 0, 0, 3, 1 },
{ 0, 0, 3, 0, 1, 0, 0, 8, 0 },
{ 9, 0, 0, 8, 6, 3, 0, 0, 5 },
{ 0, 5, 0, 0, 9, 0, 6, 0, 0 },
{ 1, 3, 0, 0, 0, 0, 2, 5, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 7, 4 },
{ 0, 0, 5, 2, 0, 6, 3, 0, 0 }
};

print(grid);
_rt_str::String s = _rt_str::String("Hello ");
printf("Content: %s\n", s.getRaw());
printf("Length: %d\n", s.getLength());
printf("Capacity: %d\n\n", s.getCapacity());
s.append("World!");
printf("Content: %s\n", s.getRaw());
printf("Length: %d\n", s.getLength());
printf("Capacity: %d\n\n", s.getCapacity());
s.append('?');
printf("Content: %s\n", s.getRaw());
printf("Length: %d\n", s.getLength());
printf("Capacity: %d\n\n", s.getCapacity());
s.append('!');
printf("Content: %s\n", s.getRaw());
printf("Length: %d\n", s.getLength());
printf("Capacity: %d\n\n", s.getCapacity());
printf("Equals: %d\n", s.opEquals("Hello World!?!"));
printf("Equals: %d\n", s.opEquals("Hello World!!"));
printf("Not Equals: %d\n", s.opNotEquals("Hello World!?!"));
printf("Not Equals: %d\n", s.opNotEquals("Hello World!!"));
s.clear();
printf("Content: %s\n", s.getRaw());
printf("Length: %d\n", s.getLength());
printf("Capacity: %d\n\n", s.getCapacity());
s.reserve(100l);
printf("Content: %s\n", s.getRaw());
printf("Length: %d\n", s.getLength());
printf("Capacity: %d\n\n", s.getCapacity());
s = _rt_str::String("");
printf("Empty: %d\n", s.isEmpty());
s.append('a');
printf("Empty: %d", s.isEmpty());
}

/*import "std/net/http" as http;
Expand Down
11 changes: 7 additions & 4 deletions src/analyzer/AnalyzerVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ std::any AnalyzerVisitor::visitFunctionCall(FunctionCallNode *node) {
throw SemanticError(node->codeLoc, REFERENCED_UNDEFINED_FUNCTION,
"Symbol '" + scopePath.getScopePrefix() + identifier + "' was used before defined");
thisType = symbolEntry->type.getBaseType();
} else if (symbolEntry != nullptr && symbolEntry->type.getBaseType().is(TY_STRUCT)) {
} else if (symbolEntry != nullptr && symbolEntry->type.getBaseType().is(TY_STRUCT)) { // last fragment is a struct
// Get the concrete template types
std::vector<SymbolType> concreteTemplateTypes;
if (node->isGeneric) {
Expand All @@ -1937,7 +1937,7 @@ std::any AnalyzerVisitor::visitFunctionCall(FunctionCallNode *node) {

functionName = CTOR_VARIABLE_NAME;
constructorCall = true;
} else {
} else { // last fragment is no struct
functionName = identifier;
continue;
}
Expand All @@ -1961,6 +1961,8 @@ std::any AnalyzerVisitor::visitFunctionCall(FunctionCallNode *node) {
argTypes.push_back(any_cast<SymbolType>(visit(arg)));
}

scopePath = scopePathBackup;

// Set to root scope if it did not change
if (accessScope == currentScope)
accessScope = rootScope;
Expand Down Expand Up @@ -2018,8 +2020,9 @@ std::any AnalyzerVisitor::visitFunctionCall(FunctionCallNode *node) {

// If the return type is an external struct, initialize it
if (!scopePathBackup.isEmpty() && returnType.is(TY_STRUCT) && scopePathBackup.getCurrentScope()->isImported(currentScope)) {
SymbolType symbolType = initExtStruct(currentScope, scopePathBackup.getScopePrefix(false), returnType.getSubType(),
returnType.getTemplateTypes(), node->codeLoc);
std::string scopePrefix = scopePathBackup.getScopePrefix(!spiceFunc->isGenericSubstantiation);
SymbolType symbolType =
initExtStruct(currentScope, scopePrefix, returnType.getSubType(), returnType.getTemplateTypes(), node->codeLoc);
return node->setEvaluatedSymbolType(symbolType);
}

Expand Down
9 changes: 2 additions & 7 deletions src/analyzer/OpRuleManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,8 @@ SymbolType OpRuleManager::getPlusResultType(const AstNode *declNode, const Symbo
}

// Allow string + string
if (lhs.is(TY_STRING) && rhs.is(TY_STRING)) {
if (!lhs.isStringStruct() && !rhs.isStringStruct()) { // If lhs and rhs are raw strings -> insert anon symbol
return analyzer->insertAnonStringStructSymbol(declNode);
} else { // Otherwise just return the type
return SymbolType(TY_STRING, "", {.isStringStruct = true}, {});
}
}
if (lhs.is(TY_STRING) && rhs.is(TY_STRING))
return analyzer->insertAnonStringStructSymbol(declNode);

return validateBinaryOperation(declNode->codeLoc, PLUS_OP_RULES, "+", lhs, rhs);
}
Expand Down
10 changes: 5 additions & 5 deletions src/generator/GeneratorVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1988,11 +1988,12 @@ std::any GeneratorVisitor::visitAdditiveExpr(AdditiveExprNode *node) {
PtrAndValue result = {nullptr, nullptr};
switch (opQueue.front().first) {
case AdditiveExprNode::OP_PLUS:
if (rhsSymbolType.isStringStruct()) {
rhs = materializeString(resolveAddress(rhsOperand));
} else {
rhs = resolveValue(rhsOperand);
if (lhsSymbolType.isStringStruct()) {
llvm::Value *lhsPtr = insertAlloca(lhs->getType());
builder->CreateStore(lhs, lhsPtr);
lhs = materializeString(lhsPtr);
}
rhs = rhsSymbolType.isStringStruct() ? materializeString(resolveAddress(rhsOperand)) : resolveValue(rhsOperand);
result = conversionsManager->getPlusInst(lhs, rhs, lhsSymbolType, rhsSymbolType, currentScope, rhsOperand->codeLoc);
break;
case AdditiveExprNode::OP_MINUS:
Expand Down Expand Up @@ -3102,7 +3103,6 @@ bool GeneratorVisitor::insertDestructorCall(const CodeLoc &codeLoc, SymbolTableE
}

llvm::Value *GeneratorVisitor::materializeString(llvm::Value *stringStructPtr) {
// assert(stringStructPtr->getType()->isPointerTy());
llvm::Value *rawStringValue = builder->CreateCall(stdFunctionManager->getStringGetRawFct(), stringStructPtr);
return rawStringValue;
}
Expand Down
6 changes: 6 additions & 0 deletions src/generator/OpRuleConversionsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,12 @@ PtrAndValue OpRuleConversionsManager::getPlusInst(llvm::Value *lhsV, llvm::Value
case COMB(TY_CHAR, TY_CHAR):
return {.value = builder->CreateAdd(lhsV, rhsV)};
case COMB(TY_STRING, TY_STRING): {
/*llvm::Function *getRawFct = stdFunctionManager->getStringGetRawFct();
if (lhsSTy.isStringStruct())
lhsV = builder->CreateCall(getRawFct, lhsV);
if (rhsSTy.isStringStruct())
rhsV = builder->CreateCall(getRawFct, rhsV);*/

// Generate call to the constructor ctor(string, string) of the String struct
llvm::Function *opFct = stdFunctionManager->getStringCtorStringStringFct();
llvm::Value *thisPtr = generator->insertAlloca(StdFunctionManager::getStringStructType(*context));
Expand Down
4 changes: 2 additions & 2 deletions src/generator/StdFunctionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ llvm::Function *StdFunctionManager::getStringMulOpShortFct() const {
return getProcedure("_mp__String__opMul__short", {builder->getPtrTy(), builder->getInt16Ty()});
}

llvm::Function *StdFunctionManager::getFunction(const std::string functionName, llvm::Type *returnType,
llvm::Function *StdFunctionManager::getFunction(const std::string &functionName, llvm::Type *returnType,
llvm::ArrayRef<llvm::Type *> args, bool varArg) const {
llvm::Function *opFct = module->getFunction(functionName);
if (opFct != nullptr)
Expand All @@ -86,7 +86,7 @@ llvm::Function *StdFunctionManager::getFunction(const std::string functionName,
return module->getFunction(functionName);
}

llvm::Function *StdFunctionManager::getProcedure(const std::string procedureName, llvm::ArrayRef<llvm::Type *> args,
llvm::Function *StdFunctionManager::getProcedure(const std::string &procedureName, llvm::ArrayRef<llvm::Type *> args,
bool varArg) const {
return getFunction(procedureName, builder->getVoidTy(), args, varArg);
}
4 changes: 2 additions & 2 deletions src/generator/StdFunctionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class StdFunctionManager {
llvm::Module *module;

// Private methods
llvm::Function *getFunction(std::string functionName, llvm::Type *returnType, llvm::ArrayRef<llvm::Type *> args,
llvm::Function *getFunction(const std::string &functionName, llvm::Type *returnType, llvm::ArrayRef<llvm::Type *> args,
bool varArg = false) const;
[[nodiscard]] llvm::Function *getProcedure(std::string procedureName, llvm::ArrayRef<llvm::Type *> args,
[[nodiscard]] llvm::Function *getProcedure(const std::string &procedureName, llvm::ArrayRef<llvm::Type *> args,
bool varArg = false) const;
};
4 changes: 3 additions & 1 deletion src/symbol/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ Function Function::substantiateGenerics(const ParamList &concreteParamList, cons
// Substantiate return type
SymbolType newReturnType = returnType.is(TY_GENERIC) ? concreteGenericTypes.at(returnType.getSubType()) : returnType;

return Function(name, specifiers, concreteThisType, newReturnType, concreteParamList, {}, declNode);
Function substantiatedFunction(name, specifiers, concreteThisType, newReturnType, concreteParamList, {}, declNode);
substantiatedFunction.isGenericSubstantiation = true;
return substantiatedFunction;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/symbol/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Function {
[[nodiscard]] const CodeLoc &getDeclCodeLoc() const;

// Public members
bool isGenericSubstantiation = false;
bool isAlreadyAnalyzed = false;
bool isUsed = false;

Expand Down
4 changes: 3 additions & 1 deletion src/symbol/Struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ Struct Struct::substantiateGenerics(const std::vector<SymbolType> &concreteTempl
}
}

return Struct(name, specifiers, currentFieldTypes, concreteTemplateTypesGeneric, declNode);
Struct substantiatedStruct(name, specifiers, currentFieldTypes, concreteTemplateTypesGeneric, declNode);
substantiatedStruct.isGenericSubstantiation = true;
return substantiatedStruct;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/symbol/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Struct {
static std::string getSignature(const std::string &structName, const std::vector<SymbolType> &concreteTemplateTypes);

// Public members
bool isGenericSubstantiation = false;
bool isUsed = false;

private:
Expand Down
5 changes: 3 additions & 2 deletions std/net/http.spice
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public type HttpServer struct {
*/
public p HttpServer.ctor(unsigned short port = HTTP_PORT_DEFAULT) {
this.port = port;
initialized = true;
this.initialized = true;
}

/**
Expand All @@ -35,10 +35,11 @@ public f<bool> HttpServer.start() {
if !this.initialized { return false; }

// Setup TCP socket
this.socket = sock.openServerSocket(port, CONNECTIONS_LIMIT);
this.socket = sock.openServerSocket(this.port, CONNECTIONS_LIMIT);

}

public f<bool> HttpServer.serve(string path, string htmlContent) {

return false;
}
Loading

0 comments on commit 20be089

Please sign in to comment.