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 and extend string runtime #209

Merged
merged 4 commits into from
Oct 8, 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
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