Giter Club home page Giter Club logo

spice's People

Contributors

dependabot[bot] avatar marcauberer avatar vedantmgoyal9 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

gmh5225

spice's Issues

Segfault when function name matches the import identifier

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));
}

Assertion fails for external struct, passed to another external function

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());
}

Logical and/or function verification error

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 ]

Compiler runs forever if accessing a member by omitting the `this.` prefix

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.

Faulty variable value updates

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

Array function params cannot be indexed

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!"

Std not accessible on Linux

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

Crash when passing too many parameters to a function / procedure

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.

External struct assertion error

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.

Crash when `sizeof` expects a value, but gets a type

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.

Double sign bug

Since v0.6.0 the compiler crashes whenever double literals are signed.

Example:

double d = -4.5;

Error when trying to build

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

Improve compiler '-version' info

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

Wrong return type of function call

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.

Could not use global variables in other modules

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.

Sizeof does not work for some types

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

Bug in nested in-place array initialization

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

Segfault when having function calls in if headers

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.

Docker container lib not found error message

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

Crash when trying to access non-primitive struct fields under certain circumstances

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

Failed to call compiler executable within Docker container

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

Install command in Docker container

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.

Split up type information from Type to Type and QualType

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.

Compiler stuck in certain situations

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.

Error using dev-setup script on Linux amd64

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

Linker error on amd64 Linux host

/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;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.