spicelang / spice Goto Github PK
View Code? Open in Web Editor NEWSpice Programming Language
Home Page: https://www.spicelang.com
License: MIT License
Spice Programming Language
Home Page: https://www.spicelang.com
License: MIT License
Demo code:
import "std/math/abs" as abs;
f<int> main() {
printf("Abs: %d\n", abs.abs(-10));
}
The term abs.abs
causes the problem.
This code works:.
import "std/math/abs" as mathAbs;
f<int> main() {
printf("Abs: %d\n", mathAbs.abs(-10));
}
Example code:
import "std/data/vector" as vec;
import "std/data/pair" as pair;
f<int> main() {
vec::Vector<pair::Pair<int, string>> pairVector = vec.Vector<pair::Pair<int, string>>();
pairVector.pushBack(pair.Pair<int, string>(0, "Hello"));
pairVector.pushBack(pair.Pair<int, string>(1, "World"));
pair::Pair<int, string> p1 = pairVector.get(1); // Here fails the assertion
printf("Hello %s!", p1.getSecond());
}
In methods of a struct, variables called the same as a field of the parent struct cause problems (even crashes).
Source code:
f<int> countLiveNeighbourCell(int[5][4] a, 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 a[i][j] == 1 {
count++;
}
}
}
return count;
}
Error message:
Internal compiler error at 47:1 - Invalid function: PHI node entries do not match predecessors!
%lor_phi8 = phi i1 [ %56, %land.end ], [ %69, %lor.1 ], [ %74, %lor.2 ]
label %lor.2
label %lor.end3
Instruction does not dominate all uses!
%69 = load i1, i1* %21, align 1
%lor_phi8 = phi i1 [ %56, %land.end ], [ %69, %lor.1 ], [ %74, %lor.2 ]
Instruction does not dominate all uses!
%74 = load i1, i1* %24, align 1
%lor_phi8 = phi i1 [ %56, %land.end ], [ %69, %lor.1 ], [ %74, %lor.2 ]
The compiler accepts something like this but runs forever:
public type Vector<T> struct {
T* contents
unsigned long capacity
unsigned long size
unsigned int itemSize
}
public f<T> Vector.get(long index) {
if (index <= size) { // Note 'size' instead 'this.size'
// ...
}
// ...
}
This is presumably caused by an infinite loop.
Source code:
int v1 = 10;
int v2 = v1;
printf("v1: %d, v2: %d\n", v1, v2);
v2++;
printf("v1: %d, v2: %d\n", v1, v2);
Expected:
v1: 10, v2: 10
v1: 10, v2: 11
Actual output:
v1: 10, v2: 10
v1: 11, v2: 11
Just stumbled over a bug, which should be fixed before being able to support cli args.
Whenever an array type is passed to a function and is indexed later, the compiler crashes in the visitIdenValue()
method when generating the GEP instruction.
This is the error message:
Assertion failed!
Program: C:\Users\i516467\Documents\JustForFunGitHubClones\spice\compiler\cmake-build-debug\src\Spice_run.exe
File: C:/Users/i516467/Documents/JustForFunGitHubClones/llvm-project/llvm/include/llvm/IR/Instructions.h, Line 921
Expression: Ty && "Invalid GetElementPtrInst indices for type!"
Sample code:
import "std/io/dir" as dir;
f<int> main() {
dir.mkDir("./this-is-a-test", dir.MODE_ALL_RWX);
printf("Created dir");
}
Spice CLI error message:
Compiler exited with status code 1
Failed to compile: Semantic error at 1:8: Imported source file not existing: The source file 'std/io/dir.spice' was not found in the standard library
Passing too many parameters to a function or procedure leads to an empty output / crash at the moment.
The cause of this issue might be the fact, that the compiler loops through all present parameters and looks them up in the symbol table for existence.
Main file:
import "std/net/socket" as socket;
f<int> main() {
socket.openServerSocket(8080s);
}
Imported file
// ...
public type Socket struct {
int sock // Actual socket
short errorCode
}
// ...
public f<Socket> openServerSocket(unsigned short port) {
result = Socket{ socket(AF_INET, SOCK_STREAM, IPPROTO_IP), 0s };
// ...
}
Error message:
Compiler exited with status code -1
Failed to compile: spicec: /work/compiler/src/generator/GeneratorVisitor.cpp:2128: void GeneratorVisitor::initExtStruct(const string&, const string&): Assertion `newStructSymbol != nullptr' failed.
The compiler crashes when compiling this:
type ShoppingItem struct {
string name
double amount
string unit
}
f<int> main() {
printf("Size: %d", sizeof(ShoppingItem));
}
The sizeof
builtin expects a value but gets a type.
Crash with error message:
Assertion failed!
Program: Spice_run.exe
File: llvm\lib\IR\Constants.cpp, Line 1981
Expression: CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!"
Since v0.6.0 the compiler crashes whenever double literals are signed.
Example:
double d = -4.5;
When executing sh build.sh
:
sh build.sh
mkdir: cannot create directory ‘bin’: File exists
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Spice: Build version is set to 'dev'
-- Spice: Built by is set to ''
-- Spice: LTO for Spice is disabled.
-- Spice: Dev build for Spice is disabled.
-- Spice: Static linking for Spice is disabled.
-- Spice: Coverage reports disabled.
-- Spice: Address sanitizer disabled.
-- Found ANTLR: /home/mingo/dev/c/A_programming-languages/spice/src/thirdparty/antlr-4.12.0-complete.jar (found version "4.1")
-- Spice: Found ANTLR 4.1
CMake Error at CMakeLists.txt:23 (add_subdirectory):
add_subdirectory given source "lib/googletest" which is not an existing
directory.
-- Performing Test Terminfo_LINKABLE
-- Performing Test Terminfo_LINKABLE - Success
-- Found Terminfo: /usr/lib/x86_64-linux-gnu/libtinfo.so
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11")
-- Found zstd: /usr/lib/x86_64-linux-gnu/libzstd.so
-- Found LibXml2: /usr/lib/x86_64-linux-gnu/libxml2.so (found version "2.9.4")
-- Spice: Found LLVM 15.0.3
-- Spice: Using LLVMConfig.cmake from /home/mingo/local/clang-15/lib/cmake/llvm
-- Configuring incomplete, errors occurred!
See also "/home/mingo/dev/c/A_programming-languages/spice/bin/CMakeFiles/CMakeOutput.log".
ninja: error: loading 'build.ninja': No such file or directory
mv: cannot stat './src/spice': No such file or directory
Some compiler output i've seen in other programming languages could be added to Spice too:
On terminal the command spice
can be an alias for spice -help
instead of as it work right: an unrecognized command
On terminal spice -v
should also print the current system specific version (aka if the current active installed compiler is linux_amd64
or linux_arm64
or others)
Eventually if in the future the Spice compiler will have a dev
and stable
branch/releases, show that info with spice -v
too
A function call currently does return the return type of the function where it is located and not the return type of the function which it is calling. That leads to bugs like this:
f<double> testFunc() {
return 0.1;
}
f<int> main() {
dyn res = testFunc();
printf("%d", res);
return 0;
}
This currently evaluates to a large negative integer number, because the call testFunc()
returns an integer instead of a double.
Code to reproduce:
import "std/os/os" as os;
f<int> main() {
printf("Os: %s", os.OS_NAME);
}
The problem seems to be, that the module is destroyed after the generator of the imported file finished running. That means that the memory address of the global variable is now a dangling pointer.
Following usages of the sizeof
builtin are not working:
printf("Size of double: %d\n", sizeof(-19.34989)); // Due to the bug in doubles
printf("Size of long: %d\n", sizeof((long) 9223372036854775807)); // Due to the bug in long parsing
printf("Size of string: %d\n", sizeof("Hello Spice!")); // Returns always 0
printf("Size of struct instance: %d\n", sizeof(structInstance)); // Returns always 0
Nested in-place array initialization does not work at the moment.
Example code:
int[vertexCount][vertexCount] graph =
{ { 0, 4, 0, 0, 0, 0, 0, 8, 0 },
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
{ 0, 0, 4, 14, 10, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 } };
The compiler crashes with an assertion failure
Following source code produces a segfault
if or1() {
printf("Condition was true");
}
while this works:
while or1() {
printf("Condition was true");
}
After first investivations, it seems that the compiler tries to pop the function signature for the call from the wrong scope.
CLI can't find compiler executable when installed on Linux or in a Docker container
string[5] welcomeMessage = { "Hello", "Spice", "programmers!" };
foreach int i, string word : welcomeMessage {
printf("Word no. %d: %s\n", i, word);
}
The expected array size is 5, whereas the actual array size is 3.
The compiler extracts the constant array to a global variable. It crashes when trying to set the initial value to the global var.
Following error message occurs when executing build test.spice
on a amd64 system, using the Docker container:
Compiler exited with status code 127
Failed to compile: Error loading shared library libtinfo.so.6: No such file or directory (needed by /usr/lib/spice/spicec)
Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /usr/lib/spice/spicec)
Error relocating /usr/lib/spice/spicec: pthread_getname_np: symbol not found
Error relocating /usr/lib/spice/spicec: mallinfo: symbol not found
Error relocating /usr/lib/spice/spicec: del_curterm: symbol not found
Error relocating /usr/lib/spice/spicec: setupterm: symbol not found
Error relocating /usr/lib/spice/spicec: set_curterm: symbol not found
Error relocating /usr/lib/spice/spicec: tigetnum: symbol not found
Error relocating /usr/lib/spice/spicec: backtrace_symbols_fd: symbol not found
Error relocating /usr/lib/spice/spicec: backtrace: symbol not found
Code to reproduce (see disabled testcase generator/structs/success-struct-in-place
):
type ShoppingItem struct {
string name
double amount
string unit
}
type ShoppingCart struct {
string label
ShoppingItem[3] items
}
f<ShoppingCart> newShoppingCart() {
ShoppingItem[3] items;
items[0] = ShoppingItem { "Spaghetti", 100.0, "g" };
items[1] = ShoppingItem { "Rice", 125.5, "g" };
items[2] = ShoppingItem { "Doughnut", 6.0, "pcs" };
return ShoppingCart { "Shopping Cart", items };
}
f<int> main() {
ShoppingCart shoppingCart = newShoppingCart();
printf("Shopping cart item 1: %s", shoppingCart.items[1].name);
}
The last line (printf ...
) causes a crash in the function verification. If the verification is disabled, it generates IR successfully.
The IR looks like this:
; ModuleID = 'os-test.spice'
source_filename = "os-test.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"
%_s__ShoppingCart__string_ShoppingItemarray = type { i8*, [3 x %_s__ShoppingItem__string_double_string] }
%_s__ShoppingItem__string_double_string = type { i8*, double, i8* }
@0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@1 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@2 = private unnamed_addr constant [10 x i8] c"Spaghetti\00", align 1
@3 = private unnamed_addr constant [2 x i8] c"g\00", align 1
@4 = private unnamed_addr constant [5 x i8] c"Rice\00", align 1
@5 = private unnamed_addr constant [2 x i8] c"g\00", align 1
@6 = private unnamed_addr constant [9 x i8] c"Doughnut\00", align 1
@7 = private unnamed_addr constant [4 x i8] c"pcs\00", align 1
@8 = private unnamed_addr constant [14 x i8] c"Shopping Cart\00", align 1
@9 = private unnamed_addr constant [10 x i8] c"Spaghetti\00", align 1
@10 = private unnamed_addr constant [2 x i8] c"g\00", align 1
@11 = private unnamed_addr constant [5 x i8] c"Rice\00", align 1
@12 = private unnamed_addr constant [2 x i8] c"g\00", align 1
@13 = private unnamed_addr constant [9 x i8] c"Doughnut\00", align 1
@14 = private unnamed_addr constant [4 x i8] c"pcs\00", align 1
@15 = private unnamed_addr constant [13 x i8] c"Another Cart\00", align 1
@16 = private unnamed_addr constant [26 x i8] c"Shopping cart item 1: %s\0A\00", align 1
@17 = private unnamed_addr constant [30 x i8] c"Another cart item 2 unit: %s\0A\00", align 1
define internal %_s__ShoppingCart__string_ShoppingItemarray @_f__void__newShoppingCart() {
entry:
%result = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
%items = alloca [3 x %_s__ShoppingItem__string_double_string], align 8
%0 = alloca %_s__ShoppingItem__string_double_string, align 8
%1 = alloca %_s__ShoppingItem__string_double_string, align 8
%2 = alloca %_s__ShoppingItem__string_double_string, align 8
%3 = alloca %_s__ShoppingItem__string_double_string, align 8
%4 = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
%5 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, i32
0, i32 0
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @0, i32 0, i32 0), i8** %5, align 8
%6 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, i32
0, i32 1
store double 0.000000e+00, double* %6, align 8
%7 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, i32
0, i32 2
store i8* getelementptr inbounds ([1 x i8], [1 x i8]* @1, i32 0, i32 0), i8** %7, align 8
store [3 x %_s__ShoppingItem__string_double_string] [%_s__ShoppingItem__string_double_string { i8* getelementptr inbou
nds ([1 x i8], [1 x i8]* @0, i32 0, i32 0), double 0.000000e+00, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @1, i32
0, i32 0) }, %_s__ShoppingItem__string_double_string { i8* getelementptr inbounds ([1 x i8], [1 x i8]* @0, i32 0, i32 0
), double 0.000000e+00, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @1, i32 0, i32 0) }, %_s__ShoppingItem__string_d
ouble_string { i8* getelementptr inbounds ([1 x i8], [1 x i8]* @0, i32 0, i32 0), double 0.000000e+00, i8* getelementptr
inbounds ([1 x i8], [1 x i8]* @1, i32 0, i32 0) }], [3 x %_s__ShoppingItem__string_double_string]* %items, align 8
%8 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, i32
0, i32 0
store i8* getelementptr inbounds ([10 x i8], [10 x i8]* @2, i32 0, i32 0), i8** %8, align 8
%9 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, i32
0, i32 1
store double 1.000000e+02, double* %9, align 8
%10 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, i32
0, i32 2
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @3, i32 0, i32 0), i8** %10, align 8
%11 = load %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, align 8
%12 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %items, align
8
%13 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %items, i32 0, i32 0
store %_s__ShoppingItem__string_double_string %11, %_s__ShoppingItem__string_double_string* %13, align 8
%14 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, i32
0, i32 0
store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @4, i32 0, i32 0), i8** %14, align 8
%15 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, i32
0, i32 1
store double 1.255000e+02, double* %15, align 8
%16 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, i32
0, i32 2
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @5, i32 0, i32 0), i8** %16, align 8
%17 = load %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, align 8
%18 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %items, align
8
%19 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %items, i32 0, i32 1
store %_s__ShoppingItem__string_double_string %17, %_s__ShoppingItem__string_double_string* %19, align 8
%20 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %3, i32
0, i32 0
store i8* getelementptr inbounds ([9 x i8], [9 x i8]* @6, i32 0, i32 0), i8** %20, align 8
%21 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %3, i32
0, i32 1
store double 6.000000e+00, double* %21, align 8
%22 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %3, i32
0, i32 2
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @7, i32 0, i32 0), i8** %22, align 8
%23 = load %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %3, align 8
%24 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %items, align
8
%25 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %items, i32 0, i32 2
store %_s__ShoppingItem__string_double_string %23, %_s__ShoppingItem__string_double_string* %25, align 8
%26 = getelementptr inbounds %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray*
%4, i32 0, i32 0
store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @8, i32 0, i32 0), i8** %26, align 8
%27 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %items, align
8
%28 = getelementptr inbounds %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray*
%4, i32 0, i32 1
store [3 x %_s__ShoppingItem__string_double_string] %27, [3 x %_s__ShoppingItem__string_double_string]* %28, align 8
%29 = load %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray* %4, align 8
ret %_s__ShoppingCart__string_ShoppingItemarray %29
}
define internal %_s__ShoppingCart__string_ShoppingItemarray @_f__void__anotherShoppingCart() {
entry:
%result = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
%items = alloca [3 x %_s__ShoppingItem__string_double_string], align 8
%0 = alloca %_s__ShoppingItem__string_double_string, align 8
%1 = alloca %_s__ShoppingItem__string_double_string, align 8
%2 = alloca %_s__ShoppingItem__string_double_string, align 8
%3 = alloca [3 x %_s__ShoppingItem__string_double_string], align 8
%4 = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
%5 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, i32
0, i32 0
store i8* getelementptr inbounds ([10 x i8], [10 x i8]* @9, i32 0, i32 0), i8** %5, align 8
%6 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, i32
0, i32 1
store double 1.000000e+02, double* %6, align 8
%7 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, i32
0, i32 2
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @10, i32 0, i32 0), i8** %7, align 8
%8 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, i32
0, i32 0
store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @11, i32 0, i32 0), i8** %8, align 8
%9 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, i32
0, i32 1
store double 1.255000e+02, double* %9, align 8
%10 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, i32
0, i32 2
store i8* getelementptr inbounds ([2 x i8], [2 x i8]* @12, i32 0, i32 0), i8** %10, align 8
%11 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, i32
0, i32 0
store i8* getelementptr inbounds ([9 x i8], [9 x i8]* @13, i32 0, i32 0), i8** %11, align 8
%12 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, i32
0, i32 1
store double 6.000000e+00, double* %12, align 8
%13 = getelementptr inbounds %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, i32
0, i32 2
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @14, i32 0, i32 0), i8** %13, align 8
%14 = load %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %0, align 8
%15 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %3, i32 0, i32 0
store %_s__ShoppingItem__string_double_string %14, %_s__ShoppingItem__string_double_string* %15, align 8
%16 = load %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %1, align 8
%17 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %3, i32 0, i32 1
store %_s__ShoppingItem__string_double_string %16, %_s__ShoppingItem__string_double_string* %17, align 8
%18 = load %_s__ShoppingItem__string_double_string, %_s__ShoppingItem__string_double_string* %2, align 8
%19 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %3, i32 0, i32 2
store %_s__ShoppingItem__string_double_string %18, %_s__ShoppingItem__string_double_string* %19, align 8
%20 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %3, align 8
store [3 x %_s__ShoppingItem__string_double_string] %20, [3 x %_s__ShoppingItem__string_double_string]* %items, align
8
%21 = getelementptr inbounds %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray*
%4, i32 0, i32 0
store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @15, i32 0, i32 0), i8** %21, align 8
%22 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %items, align
8
%23 = getelementptr inbounds %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray*
%4, i32 0, i32 1
store [3 x %_s__ShoppingItem__string_double_string] %22, [3 x %_s__ShoppingItem__string_double_string]* %23, align 8
%24 = load %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray* %4, align 8
ret %_s__ShoppingCart__string_ShoppingItemarray %24
}
define i32 @main() {
entry:
%result = alloca i32, align 4
%shoppingCart = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
%0 = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
%1 = alloca %_s__ShoppingCart__string_ShoppingItemarray, align 8
store i32 0, i32* %result, align 4
%2 = call %_s__ShoppingCart__string_ShoppingItemarray @_f__void__newShoppingCart()
store %_s__ShoppingCart__string_ShoppingItemarray %2, %_s__ShoppingCart__string_ShoppingItemarray* %0, align 8
%3 = load %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray* %0, align 8
store %_s__ShoppingCart__string_ShoppingItemarray %3, %_s__ShoppingCart__string_ShoppingItemarray* %shoppingCart, alig
n 8
%4 = load %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray* %shoppingCart, ali
gn 8
%5 = getelementptr inbounds %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray*
%shoppingCart, i32 0, i32 1
%6 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %5, align 8
%7 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_strin
g]* %5, i32 0, i32 1
%8 = load i8*, i8** %11, align 8
%9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @16, i32 0, i32 0), i8* %8)
%10 = call %_s__ShoppingCart__string_ShoppingItemarray @_f__void__anotherShoppingCart()
store %_s__ShoppingCart__string_ShoppingItemarray %10, %_s__ShoppingCart__string_ShoppingItemarray* %1, align 8
%11 = load %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray* %1, align 8
store %_s__ShoppingCart__string_ShoppingItemarray %11, %_s__ShoppingCart__string_ShoppingItemarray* %shoppingCart, ali
gn 8
%12 = load %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray* %shoppingCart, al
ign 8
%13 = getelementptr inbounds %_s__ShoppingCart__string_ShoppingItemarray, %_s__ShoppingCart__string_ShoppingItemarray*
%shoppingCart, i32 0, i32 1
%14 = load [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_string]* %13, align 8
%15 = getelementptr inbounds [3 x %_s__ShoppingItem__string_double_string], [3 x %_s__ShoppingItem__string_double_stri
ng]* %13, i32 0, i32 2
%16 = load i8*, i8** %13, align 8
%17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @17, i32 0, i32 0), i8* %16)
%18 = load i32, i32* %result, align 4
ret i32 %18
}
declare i32 @printf(i8*, ...)
The placeholder %11
is used twice in the main function, but was not declared there. This causes the LLVM function verification process to fail.
Error message:
While deleting: i8** %
Use still stuck around after Def is destroyed: %8 = load i8*, i8** <badref>, align 8
Assertion failed: materialized_use_empty() && "Uses remain when a value is destroyed!", file D:/LLVM/llvm/lib/IR/Value.cpp, line 100
Dockerfile:
# Builder
FROM chillibits/spice:0.6.4 as builder
WORKDIR /usr/src
COPY . .
RUN spice build -o /usr/local/bin/example-app app.spice
# Minimalistic image
FROM scratch
COPY --from=builder /usr/local/bin/example-app /usr/local/bin/example-app
ENTRYPOINT [ "example-app" ]
Main source file:
f<int> main() {
printf("Hello World!");
}
Error message:
[+] Building 2.1s (9/10)
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 308B 0.0s
=> [internal] load .dockerignore 0.2s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/chillibits/spice:0.6.4 0.8s
=> [auth] chillibits/spice:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 391B 0.0s
=> [builder 1/4] FROM docker.io/chillibits/spice:0.6.4@sha256:ea1c61c3fab058e0c6f27652bf6087023650a1df19c0576f2f7463 0.0s
=> CACHED [builder 2/4] WORKDIR /usr/src 0.0s
=> [builder 3/4] COPY . . 0.2s
=> ERROR [builder 4/4] RUN spice build -o /usr/local/bin/example-app app.spice 0.7s
------
> [builder 4/4] RUN spice build -o /usr/local/bin/example-app app.spice:
#9 0.540 Failed to call compiler executable
------
failed to solve: rpc error: code = Unknown desc = executor failed running [/bin/sh -c spice build -o /usr/local/bin/example-app app.spice]: exit code: 1
The install command should be disabled when the Spice cli runs within a Docker container, because the output executable would be installed in the container and not on the host system.
Currently, the Type
class holds all type information: the type chain, as well as the type specifiers (qualifiers) like signedness, constness, visibility, etc. To reduce memory footprint and performance, we aim to unify types, meaning that we want a TypeRegistry, that manages all types. Whenever a new type is needed, the TypeRegistry is asked to provide the type as Type*. If the type already exists, it simply returns the pointer to that type instance, otherwise the type instance is created and put into a type map. To make this possible, we need to separate the type specifiers (qualifiers) from the type chain, because we only want to unify the type chain information. Otherwise we would have int
, signed int
, unsigned int
, public int
, etc., polluting the type map. The QualType
class should contain a pointer to a type, as well an intstance of TypeSpecifiers
.
From the Sudoku example:
foreach int[size] row : grid {
foreach int cell : row {
printf("%d ", cell);
}
printf("\n");
}
Casting char*
types to string
types is possible, does not throw a compiler error, but leads to wrong results for strings with length >= 8.
For example, the bug occurs here:
f<int> main() {
printf("%s\n", "Hello World!".substring(0, 9));
}
This code prints:
ðìl
const int AF_INET = 2;
const int SOCK_STREAM = 1;
const int SOCK_DGRAM = 2;
const int IPPROTO_IP = 0;
const int IPPROTO_UDP = 17;
const int INADDR_ANY = 0;
type InAddr struct {
unsigned int addr
}
type SockAddrIn struct {
unsigned short sinFamily
unsigned short sinPort
InAddr sinAddr
}
type Socket struct {
int sockFd // Actual socket
int connFd // Current connection
short errorCode
}
const short ERROR_SOCKET = -1s;
const short ERROR_BIND = -2s;
const short ERROR_LISTEN = -3s;
const short ERROR_ACCEPT = -4s;
ext<int> socket(int, int, int);
ext<int> bind(int, SockAddrIn*, int);
ext<int> listen(int, int);
ext<int> accept(int, SockAddrIn*, int);
ext<int> close(int);
ext<int> htonl(int); // Fairly simple to re-implement in Spice
ext<short> htons(short); // Fairly simple to re-implement in Spice
/**
* Accept an incoming connection to the socket and save the connection file desceiptor
* to the socket object.
*
* @return Connection file descriptor
*/
f<int> Socket.acceptConnection() {
SockAddrIn cliAddr = SockAddrIn {};
this.connFd = accept(this.sockFd, &cliAddr, 16 /* hardcoded sizeof(cliAddr) */);
if this.connFd == -1 {
//result.errorCode = ERROR_ACCEPT;
return -1;
}
return this.connFd;
}
p Socket.waitForIncomingConnections() {
// ToDo: Implement
}
/**
* Closes the socket. This method should always be called by the user before exiting the program.
*
* @return Error code for closing the socket
*/
f<int> Socket.close() {
return close(this.sockFd);
}
f<int> openServerSocket(unsigned short port) {
Socket s = Socket { socket(AF_INET, SOCK_STREAM, IPPROTO_IP), 0, 0s };
// Cancel on failure
if s.sockFd == -1 {
//result.errorCode = ERROR_SOCKET;
return -1;
}
InAddr inAddr = InAddr { htonl(INADDR_ANY) };
SockAddrIn servaddr = SockAddrIn { (short) AF_INET, htons(port), inAddr };
int bindResult = bind(s.sockFd, &servaddr, 16 /* hardcoded sizeof(servaddr) */);
if bindResult != 0 {
//result.errorCode = ERROR_BIND;
return -2;
}
int listenResult = listen(s.sockFd, 5 /* backlog */);
if listenResult != 0 {
//result.errorCode = ERROR_LISTEN;
return -3;
}
s.acceptConnection();
return s.sockFd;
}
// Tmp function until bug #95 is fixed
f<int> closeSocket(int fd) {
return close(fd);
}
The line s.acceptConnections()
causes the compiler to stuck (in an endless loop?). The compiler runs fine, when commenting out that particular line.
When running ./dev-setup
on my Linux amd64 i receive the following error (relevant part):
Looking for dladdr
-- Looking for dladdr - found
-- Looking for proc_pid_rusage
-- Looking for proc_pid_rusage - not found
-- Performing Test HAVE_CXX_ATOMICS_WITHOUT_LIB
-- Performing Test HAVE_CXX_ATOMICS_WITHOUT_LIB - Failed
-- Looking for __atomic_fetch_add_4 in atomic
-- Looking for __atomic_fetch_add_4 in atomic - found
-- Performing Test HAVE_CXX_ATOMICS_WITH_LIB
-- Performing Test HAVE_CXX_ATOMICS_WITH_LIB - Failed
CMake Error at cmake/modules/CheckAtomic.cmake:56 (message):
Host compiler must support std::atomic!
Call Stack (most recent call first):
cmake/config-ix.cmake:418 (include)
CMakeLists.txt:868 (include)
-- Configuring incomplete, errors occurred!
See also "/home/zodiac/spice/llvm/build-release/CMakeFiles/CMakeOutput.log".
See also "/home/zodiac/spice/llvm/build-release/CMakeFiles/CMakeError.log".
ninja: error: loading 'build.ninja': No such file or directory
done.
[Step 4] Downloading third-party libraries ...
done.
[Step 5] Building Spice ...
done.
The setup is done. Have fun coding!
Whenever you need to build Spice again, use the ./build.sh script.
Is also worth to add that the script goes on until is finished with all the required steps even though it encountered an error. It should probably quit after hitting an error
Full Log files added
CMakeError.log
CMakeOutput.log
/usr/bin/ld: output.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
Error occurred in Spice 0.2.0 on a Linux amd64 host when compiling following program:
f<int> main() {
printf("Hello World!");
return 0;
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.