Giter Site home page Giter Site logo

circle's People

Contributors

adavidzh avatar brycelelbach avatar seanbaxter avatar x432ph 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  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  avatar  avatar

Watchers

 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

circle's Issues

circle: "explicit constructor chosen in copy-list-initialization"

The program:

#include <initializer_list>


struct lattice
{
  template<class Size1, class Size2>
  explicit lattice(const Size1& dimension1, const Size2& dimension2){}

  template<class Size>
  lattice(std::initializer_list<Size> dimensions){}
};


int main()
{
  // XXX this should choose the second constructor
  lattice l = {2, 2};

  return 0;
}

Causes circle to emit the following error message:

$ ~/Desktop/circle/circle -I. repro.cpp 
error: repro.cpp:17:13
explicit constructor chosen in copy-list-initialization
  lattice l = {2, 2}; 

clang & g++ compile the program without error.

Compiler details:

$ circle --version ; echo ; clang --version ; echo ; g++ --version
circle version 1.0.0-135
  Circle public preview build 135
  Built Sep 26 2021 22:32:16
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

About Windows support and a windows prebuilt executable?

Hi,
just noticed on twitter your circle 100 release with graphics shader C++ support..
seems you only ship
is this project buildable on Windows? i.e. has Windows support?
in case yes.. better yet.. can you provide Windows prebuilt binaries (circle.exe)?
thanks..

introspection on bitfield data members

First: circle is incredible! I'm amazed by the many ways it significantly improves upon conventional C++.


It looks like bitfield members work properly in circle, but the introspection tools (e.g. @member_count) for them do not:

#include <cstdio>

struct data_t {
  uint32_t foo : 7;
  uint32_t bar : 2;
  uint32_t baz : 13;
  uint32_t qux : 10;
};

struct nonbitfield_data_t {
  uint32_t foo;
  uint32_t bar;
  uint32_t baz;
  uint32_t qux;
};


template<typename type_t>
void print_members() {
  printf("%s has %i members:\n", @type_string(type_t), @member_count(type_t));
  printf("%d: %s - %s\n", int..., @member_type_strings(type_t), 
    @member_names(type_t))...;
}

int main() {
  static_assert(sizeof(data_t) == 4);
  print_members<data_t>();
  printf("\n");
  print_members<nonbitfield_data_t>();
}

/* output:
data_t has 0 members:

nonbitfield_data_t has 4 members:
0: uint32_t - foo
1: uint32_t - bar
2: uint32_t - baz
3: uint32_t - qux
*/

working example: https://godbolt.org/z/j6o1jsGGY

testing done locally on ubuntu 20.04 with build_136

Build 128: Segmentation fault while compiling mandelbrot example

Something goes wrong when I try to execute mandelbrot function at compile time.
It is related to <complex>. Compiler does not output any helpful message.

./circle mandelbrot.cxx
Segmentation fault

This is expected output with handcrafted complex class.

This is how it run with std::complex<>.

mandelbrot.cxx

/// Adapted from wes' code. <https://web.archive.org/web/20210411041036/http://www.fractalforums.com/programming/mandelbrot-with-only-18-lines-of-cplusplus-code!/>
#include <cstdio>
#include <complex>

static void mandelbrot()
{
    using namespace std;
    constexpr auto kRows = 22, kCols = 78, kRuns = 20;

    for (float x: @range(kRows + 1)...)
    {
        for (float y: @range(kCols - 1)...)
        {
            complex<float> z, c { y * 2 / kCols - 1.5f, x * 2 / kRows - 1.0f };
            auto i = 0;
            while (abs(z) < 2 and ++i < kRuns)
                z = pow(z, 2.0f) + c;
            putchar(i != kRuns ? '.' : '#');
        }
        putchar('\n');
    }
}

int main()
{
    @meta mandelbrot();
    mandelbrot();
}

Compiler segfaults when compiling eprintf example

Running on Linux 5.6.4-arch1-1 with a freshly cloned repo

$ build_96/circle circle/examples/eprintf/eprintf.cxx
Segmentation fault (core dumped)

I would try to debug a bit, but alas... no debug symbols in the compiler.

circle: "Unexpected # in token stream" when macro used to define a pragma

The program

#include <cuda_runtime_api.h>
#include <iostream>
#include <utility>

#define EXEC_CHECK_DISABLE #pragma nv_exec_check_disable

EXEC_CHECK_DISABLE
template<class F>
__host__ __device__ auto invoke(F&& f)
{
  return std::forward<F>(f)();
}

__global__ void kernel()
{
  invoke([]
  {
    printf("invoke called from __device__\n");
  });
}

int main()
{
  invoke([]
  {
    std::cout << "invoke called from __host__" << std::endl;
  });

  kernel<<<1,1>>>();
  cudaDeviceSynchronize();

  std::cout << "OK" << std::endl;

  return 0;
}

Causes circle to emit the following error message

$ circle --cuda-path=/usr/local/cuda -sm_50 repro.cu -lcudart
preprocessor: repro.cu:7:1
unexpected # in token stream

Compiler details:

$ circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 23:42:52
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

C support (Perhaps opening the integration test suite?)

Is there any reason a subset of Circle cannot output valid C code? Perhaps a meta_c@ to emit compile-time evaluations that are correct C? Probably need this anyway for metas that must be in older C++ versions or avoid the use of the STL.

Probably quickest to blast test suite code with clang to see if there are errors and if so pass through clangAST to describe known C++ AST elements that are illegal in C?

When I ported Ruby 1.8 to Blue Gene/L, having the test suite was 100x more helpful than the documentation. You might consider opening an integration test suite, https://www.cs.princeton.edu/courses/archive/spring01/cs333/awktest.html

Segmentation fault amidst SFINAE

The program

#include <type_traits>


struct dispatch_foo
{
  // XXX crashes
  template<class T,
           typename std::enable_if<!std::is_arithmetic<T&&>::value>::type* = nullptr
          >
  constexpr auto operator()(T&&) const
    -> decltype(operator()<T>())
  {
    return operator()<T>();
  }


//  // XXX doesn't crash
//  template<class T,
//           class = std::enable_if_t<!std::is_arithmetic<T&&>::value>
//          >
//  constexpr auto operator()(T&&) const
//    -> decltype(operator()<T>())
//  {
//    return operator()<T>();
//  }
};


constexpr const dispatch_foo foo;


void main()
{
  foo(13);
}

Causes a segmentation fault when compiled with circle:

$ /home/jhoberock/Desktop/circle/circle -std=c++17 segmentation_fault.cpp 
Segmentation fault (core dumped)

An alternative spelling of the SFINAE guard correctly produces a compiler error.

Compiler details:

$ /home/jhoberock/Desktop/circle/circle --version
circle version 1.0.0-134
  Circle public preview build 134
  Built Sep 25 2021 16:55:11
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

circle binary depends on specific library versions not installed (libffi)

I downloaded your build_81. Your circle executable there required libffi.so.6. On my Centos 6 + x86_64 system, I have libffi .so.5, so circle no workee.

Then low and behold trying to build libffi downloaded from github is a big fail.

Your concept for circle is very appealing. But you need to open it up somehow so folks like me can actually try to use it.

Thanks for your efforts. I hope they are successful because circle does look like a good idea. In fact, the peglib thing is what got me to look at it. I wish it worked for me right out of the box, because then I'd probably be spending lots of time thinking about the possibilities.

I may come back after some time passes and check out your progress.

the language is an awesome idea but has unclear business model

I just heard about Circle on cppcast and I must say I'm impressed. I hope It's not going to sound too much like I'm a know-it-all, but I'm going to suggest a change in business model. I don't know all the facts and I may get some things wrong, but I wanted to write this anyway, because I may have some ideas you can use.

The problem currently is that it's closed source and it could disappear any day, so I don't think people will take it seriously (I for sure wouldn't use it for commercial projects right now). I know it's a chicken and egg problem though (you may not get funding if you release the source).

Idea 1:

Why not make implementation open-source, build a community of users and then make money on consulting? It looks a bit like you are trying to repeat what Bjarne Stroustrup did, but it's not the 1980s anymore.

Or maybe make the main language open-source and keep some tools (a non-essential one like a performance analyzer) paid?

Idea 2

In any case, I think you can learn a lot from the story of the D programming language. It is slowly gaining traction but its future is unclear because it has it's complications and it's not a big enough improvement over C++. An example of such feature is compile-time regex, but this is not important enough to make people switch languages.

A way for Circle to grow could be by creating a unique use case that could not be done easily in C++. Maybe see what Halide (https://halide-lang.org/) does, and see if you can replicate some or all of that with the compile-time magic of Circle. That could make you the king of HPC.

Idea 3

One of the historical problems of D was a closed-source implementation. Some people just didn't want to work with such a tool. Also, even after open-sourcing it, the level of community contribution to the language itself was very small until the implementation began being hosted on Github. This is really important. There is always GNU GPL licence to use if you want to restrict commercial uses somewhat but I'm not sure how it would influence the behavior of the people you are pitching the language to.

Dockerfile is invalid

The docker file provided at https://www.circle-lang.org/Dockerfile is not valid.

Dockerfile as downloaded:

FROM ubuntu:18.04

MAINTAINER Sean <[email protected]>

RUN apt-get update && \
  apt-get install -y binutils libstdc++-8-dev wget git && \
  wget -P /home https://www.circle-lang.org/debian/build_97.tgz && \
  tar xvf /home/build_98.tgz -C /usr/bin && \
  chmod +x /usr/bin/circle && \
  git clone https://www.github.com/seanbaxter/circle /home/circle_docs

Output:

$ docker build --tag=circle_docker .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:18.04
[...]
done
--2020-06-07 13:15:03--  https://www.circle-lang.org/debian/build_97.tgz
Resolving www.circle-lang.org (www.circle-lang.org)... 64.90.37.113
Connecting to www.circle-lang.org (www.circle-lang.org)|64.90.37.113|:443... connected.
HTTP request sent, awaiting response... 404 Not Found
2020-06-07 13:15:04 ERROR 404: Not Found.

The command '/bin/sh -c apt-get update &&   apt-get install -y binutils libstdc++-8-dev wget git &&   wget -P /home https://www.circle-lang.org/debian/build_97.tgz &&   tar xvf /home/build_98.tgz -C /u

Updated file to fix the URL: (https://www.circle-lang.org/debian/build_97.tgz -> https://www.circle-lang.org/linux/build_98.tgz)

FROM ubuntu:18.04

MAINTAINER Sean <[email protected]>

RUN apt-get update && \
  apt-get install -y binutils libstdc++-8-dev wget git && \
  wget -P /home https://www.circle-lang.org/linux/build_98.tgz && \
  tar xvf /home/build_98.tgz -C /usr/bin && \
  chmod +x /usr/bin/circle && \
  git clone https://www.github.com/seanbaxter/circle /home/circle_docs

Output:

$ docker build --tag=circle_docker .
[...]
Successfully tagged circle_docker:latest
$ docker run -it circle_docker bash
# cd /home/circle_docs/examples/special
# circle special.cxx
circle: error while loading shared libraries: libelf.so.1: cannot open shared object file: No such file or directory

Updated file to install libelf-dev

FROM ubuntu:18.04

MAINTAINER Sean <[email protected]>

RUN apt-get update && \
  apt-get install -y binutils libstdc++-8-dev libelf-dev wget git && \
  wget -P /home https://www.circle-lang.org/linux/build_98.tgz && \
  tar xvf /home/build_98.tgz -C /usr/bin && \
  chmod +x /usr/bin/circle && \
  git clone https://www.github.com/seanbaxter/circle /home/circle_docs

Output:

$ docker build --tag=circle_docker .
[...]
Successfully tagged circle_docker:latest
$ docker run -it circle_docker bash
# cd /home/circle_docs/examples/special
# circle special.cxx
circle: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by circle)

Updated file to install a newer version of libstdc++ (libstdc++-9-dev). This requires a newer version of Ubuntu (20.04)

FROM ubuntu:20.04

MAINTAINER Sean <[email protected]>

RUN apt-get update && \
  apt-get install -y binutils libstdc++-9-dev libelf-dev wget git && \
  wget -P /home https://www.circle-lang.org/linux/build_98.tgz && \
  tar xvf /home/build_98.tgz -C /usr/bin && \
  chmod +x /usr/bin/circle && \
  git clone https://www.github.com/seanbaxter/circle /home/circle_docs

Output:

$ docker build --tag=circle_docker .
[...]
Successfully tagged circle_docker:latest
$ docker run -it circle_docker bash
# cd /home/circle_docs/examples/special
# circle special.cxx
Generating code for function 'E1'
  note: first Einstein special function
  Injecting expression 'sq(x) * exp(x) / sq(exp(x) - 1)'
  Injecting Taylor series
Generating code for function 'factorial'
  Injecting statements 'double y = 1; while(x > 1) y *= x--; return y;'
Generating code for function 'sigmoid'
  Injecting expression '1 / (1 + exp(-x))'
  Injecting Taylor series
Generating code for function 'sin'
  Injecting expression 'sin(x)'
  Injecting Taylor series
Generating code for function 'tanh'
  Injecting expression 'tanh(x)'
  Injecting Taylor series
error: /usr/include/string.h:73:20
cannot overload void* memchr(const void*, int, unsigned long) noexcept on return type
  previous declaration at <implicit declaration>
extern const void *memchr (const void *__s, int __c, size_t __n) 
                   ^

error: /usr/include/string.h:208:20
cannot overload char* strchr(const char*, int) noexcept on return type
  previous declaration at <implicit declaration>
extern const char *strchr (const char *__s, int __c) 
                   ^

error: /usr/include/string.h:312:20
cannot overload char* strstr(const char*, const char*) noexcept on return type
  previous declaration at <implicit declaration>
extern const char *strstr (const char *__haystack, const char *__needle) 
                   ^

Including both string and cstring causes compiler error

Example program:

#include <string>
#include <cstring>

int main() {
        return 0;
}

Output:

# circle test.cxx
error: /usr/include/string.h:73:20
cannot overload void* memchr(const void*, int, unsigned long) noexcept on return type
  previous declaration at <implicit declaration>
extern const void *memchr (const void *__s, int __c, size_t __n) 
                   ^

error: /usr/include/string.h:208:20
cannot overload char* strchr(const char*, int) noexcept on return type
  previous declaration at <implicit declaration>
extern const char *strchr (const char *__s, int __c) 
                   ^

error: /usr/include/string.h:312:20
cannot overload char* strstr(const char*, const char*) noexcept on return type
  previous declaration at <implicit declaration>
extern const char *strstr (const char *__haystack, const char *__needle) 
                   ^

Type with defaulted spaceship operator fails std::equality_comparable

The program

#include <concepts>
#include <compare>

struct foo
{
  auto operator<=>(const foo&) const = default;
};

struct bar
{
  bool operator==(const bar&) const
  {
    return true;
  }
};

int main()
{
  static_assert(std::equality_comparable<foo>);
  static_assert(std::equality_comparable<bar>);
}

Causes circle to emit the error

$ circle -std=c++20 repro.cpp 
error: repro.cpp:19:3
static_assert failed
  static_assert(std::equality_comparable<foo>); 
  ^

error: translation aborted; too many errors

clang correctly compiles this program.

Compiler details:

$ circle --version ; echo ; clang --version
circle version 1.0.0-137
  Circle public preview build 137
  Built Oct  7 2021 23:28:38
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

circle: "undeclared identifier" in macro

When compiled with circle, the program:

#include <type_traits>

#  define CONCATENATE_IMPL(x, y) x##y

#  define CONCATENATE(x, y) CONCATENATE_IMPL(x, y)

#  define MAKE_UNIQUE(x) CONCATENATE(x, __COUNTER__)

#  define REQUIRES_IMPL(unique_name, ...) bool unique_name = true, typename std::enable_if<(unique_name and __VA_ARGS__)>::type* = nullptr

#  define REQUIRES(...) REQUIRES_IMPL(MAKE_UNIQUE(__deduced_true), __VA_ARGS__)


struct foo
{
  template<class T,
           REQUIRES(std::is_arithmetic<T>::value)
          >
  void bar();
};

int main()
{
}

Produces the following compilation error message:

$ circle -std=c++17 repro.cpp 
error: repro.cpp:17:12
undeclared identifier '__deduced_true1'
           REQUIRES(std::is_arithmetic<T>::value) 
           ^

Compiler details:

$ circle --version
circle version 1.0.0-132
  Circle public preview build 132
  Built Sep 20 2021 18:12:19
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

circle: "unsupported attribute on declaration" upon use of __managed__

The program

__managed__ int result;

int main()
{
  return 0;
}

Causes circle to emit the error message

$ circle --cuda-path=/usr/local/cuda -sm_50 repro.cu 
error: repro.cu:1:17
unsupported attribute on declaration
__managed__ int result; 
                ^

Compiler details:

$ ~/Desktop/circle/circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 23:42:52
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

Consider support for #pragma nv_exec_check_disable

#pragma nv_exec_check_disable allows users to write __host__ __device__ function templates that call either __host__ or __device__ functions in their definitions.

I understand that circle's execution space inference makes such functionality obsolete, but support for this pragma would be appreciated to make legacy codebases work.

circle: "cg: bool __atomic_test_and_set(volatile void*, int) noexcept not implemented"

The program

#include <future>

int main()
{
  std::promise<int> p;
  p.get_future();
  return 0;
}

Causes circle to emit the error message:

$ ~/Desktop/circle/circle repro.cpp 
ODR used by: int main()
repro.cpp:6:15
  p.get_future(); 
              ^

ODR used by: std::future<int> std::promise<int>::get_future()
/usr/include/c++/9/future:1105:28
      { return future<_Res>(_M_future); } 
                           ^

ODR used by: std::future<int>::future(const std::shared_ptr<std::__future_base::_State_baseV2>&)
/usr/include/c++/9/future:773:45
      future(const __state_type& __state) : _Base_type(__state) { } 
                                            ^

ODR used by: std::__basic_future<int>::__basic_future(const std::shared_ptr<std::__future_base::_State_baseV2>&)
/usr/include/c++/9/future:733:40
        _M_state->_M_set_retrieved_flag(); 
                                       ^

ODR used by: void std::__future_base::_State_baseV2::_M_set_retrieved_flag()
/usr/include/c++/9/future:454:32
  if (_M_retrieved.test_and_set()) 
                               ^

  error: /usr/include/c++/9/bits/atomic_base.h:195:36
  ... included from /usr/include/c++/9/bits/shared_ptr_atomic.h:33:10
  ... included from /usr/include/c++/9/memory:82:12
  ... included from /usr/include/c++/9/thread:39:10
  ... included from /usr/include/c++/9/future:39:10
  ... included from repro.cpp:1:10
  cg: bool __atomic_test_and_set(volatile void*, int) noexcept not implemented
        return __atomic_test_and_set (&_M_i, int(__m)); 

Compiler details:

$ ~/Desktop/circle/circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 11:04:48
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

Missing aggregate constructor in type with deleted copy constructor

The program

template<class T>
struct noncopyable
{
  T x;

  noncopyable(const noncopyable&) = delete;
};


int main()
{
  noncopyable<int> x{13};

  return 0;
}

Causes circle to emit the following error message:

$ circle repro.cpp
error: repro.cpp:12:22
cannot convert prvalue int to const noncopyable<int>&
  noncopyable<int> x{13}; 

Compiler details:

$ ~/Desktop/circle/circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 11:04:48
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

bug with -g option

circle (build 93) segfaults when compiling the following program with -g.

// test.cc
#include <iostream>

#include "nlohmann/json.hpp"

using json = nlohmann::json;

int main() {
  json j = "hi there!";
  std::cout << j;
  return 0;
}

code was compiled with circle test.cc -Ipath/to/nlohmann/json/include -g, using g++ produces no error.

circle: "error forming list comprehension" when compiling __device__ lambda

The program

int main()
{
  auto device_lambda = [] __device__ () {};
  return 0;
}

Causes circle to emit the error message

$ circle --cuda-path=/usr/local/cuda -sm_50 repro.cu 
error: repro.cu:3:24
error forming list comprehension
  auto device_lambda = [] __device__ () {}; 
                       ^
  error: repro.cu:3:25
  expected 1 or more items in initializer-list
    auto device_lambda = [] __device__ () {}; 

Compiler details:

$ ~/Desktop/circle/circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 23:42:52
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

Question: What is the state of SIMD support in circle?

Hi, I'm interested in using circle's metaprogramming tools to extend an existing codebase that makes use of SIMD intrinsics, but it seems to be failing to compile. A small example here (code below)

#include <immintrin.h>

struct vec4 {
    double values[4];
    double & operator()(int i) { return values[i]; }
    const double & operator()(int i) const { return values[i]; }
};

vec4 plus(const vec4 & x, const vec4 & y) {
    return vec4{x(0) + y(0), x(1) + y(1), x(2) + y(2), x(3) + y(3)};
}

vec4 operator+(const vec4 & x, const vec4 & y) {
    __m256d _x = _mm256_loadu_pd(x.values);
    __m256d _y = _mm256_loadu_pd(y.values);
    vec4 sum;
    _mm256_storeu_pd(sum.values, _mm256_add_pd(_x, _y));
    return sum;
}

illustrates the problem: errors to the tune of

vector_size 64 is unsupported
typedef char __v64qi __attribute__ ((__vector_size__ (64))); 

Meanwhile, the 128-bit intrinsics seem to compile successfully:

#include <xmmintrin.h>

struct vec2 {
    double values[2];
    double & operator()(int i) { return values[i]; }
    const double & operator()(int i) const { return values[i]; }
};

vec2 plus(const vec2 & x, const vec2 & y) {
    return vec2{x(0) + y(0), x(1) + y(1)};
}

vec2 operator+(const vec2 & x, const vec2 & y) {
    __m128d _x = _mm_loadu_pd(x.values);
    __m128d _y = _mm_loadu_pd(y.values);
    vec2 sum;
    _mm_storeu_pd(sum.values, _mm_add_pd(_x, _y));
    return sum;
}

With gcc/clang, flags (e.g. -mavx) are sometimes needed to enable the larger intrinsics, I was wondering if there is something similar that needs to be passed to circle or if these are currently unsupported.

These examples were tested against build_136 on Ubuntu 20.04, as well as compiler explorer's "Latest" circle option (unsure what version that actually is).

Output C++ instead of IR

I've something similar to Circle on my TODO list for ages to replace the preprocessor.

I feel like outputting C++ would be great as many projects can't use LLVM, video games and embedded come to mind.

Is it possible at all?

circle: "Undeclared identifier 'is_same_v'" when #include <array>

The program:

#include <array>

int main()
{
  return 0;
}

Yields the following compiler error message:

$ ~/Desktop/circle/circle -std=c++14 repro.cpp 
error: /usr/include/c++/9/array:245:29
... included from repro.cpp:1:10
undeclared identifier 'is_same_v'
      -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>, 

Cannot find function __cudaPopCallConfiguration in CUDA Toolkit

I'm trying to use the latest compiler version (96), to compile example https://www.circle-lang.org/saxpy.html. I'm using ubuntu 18.04 and installed the cuda package version 10.2 from https://developer.nvidia.com/cuda-downloads.

circle -cuda-path /usr/local/cuda-10.2 -sm_35 -sm_52 -sm_61 -sm_70 saxpy.cu -lcudart

results in

error: cannot find function __cudaPopCallConfiguration in CUDA Toolkit

I ran

objdump -D /usr/local/cuda-10.2/lib64/libcudart.so | grep __cudaPopCallConfiguration

and this symbol seems to be present.

make opensource or crowdfund

I hope project will find support (patreon, maybe?) or become opensource, otherwise it will be risky to use with big production code bases.

Better C++ example for loop unrolling

Your overall point, that you have write weird code to things at compile time, still stands, but I think a fair comparison against C++ would probably have the code look more like this:

#include <cstddef>
#include <cstdio>
#include <utility>

template<std::size_t first, std::size_t last, typename Function>
constexpr void unroll(Function && function) {
	[&]<std::size_t... indexes>(std::index_sequence<indexes...>) {
		(..., function(std::integral_constant<std::size_t, indexes + first>()));
	}(std::make_index_sequence<last - first>());
}


template<int I>
void func(int & x) {
    x *= 2;
    printf("After I = %d, x = %d\n", I, x);
}

int main() {
  int x = 1;
  unroll<0, 5>([&](auto i) {
      func<i.value>(x);
  });
}

The unroll code is pretty strange (because we do not yet have for...), but it can at least be a reusable library function. Importantly, the usage side is much simpler: you can access the static constexpr member of an integral_constant by just using normal member variable syntax. No need for a local enum and decltype.

Use of std::declval misses perfect forwarding function during overload resolution

The program

#include <type_traits>

struct dispatch_foo
{
  template<class T,
           class = std::enable_if_t<std::is_arithmetic<T>::value>
          >
  constexpr int operator()() const
  {
    return 0;
  }


  template<class T,
           class = std::enable_if_t<std::is_reference<T&&>::value>
          >
  constexpr auto operator()(T&&) const
    -> decltype(operator()<std::decay_t<T&&>>())
  {
    return operator()<std::decay_t<T&&>>();
  }
};


template<class T>
using foo_t = decltype(dispatch_foo{}(std::declval<T>()));


int main()
{
  foo_t<char> x;
  return 0;
}

Generates the following error message when compiled with circle:

$ circle -I. -std=c++14 repro.cpp
error: repro.cpp:26:38
no viable candidates in call to 'operator()'
  argument 0 is xvalue char
using foo_t = decltype(dispatch_foo{}(std::declval<T>())); 
                                     ^
  candidate: int dispatch_foo::operator()() const
  repro.cpp:8:17
    constexpr int operator()() const 
                  ^
    error: invalid argument count
    function expects 0 arguments

  candidate: decltype(operator()<std::decay_t<T&&>>()) dispatch_foo::operator()(T&&) const
  repro.cpp:17:18
    constexpr auto operator()(T&&) const 
                   ^
    instantiation: decltype(operator()<std::decay_t<T&&>>()) dispatch_foo::operator()(T&&) const
    during substitution of return type of decltype(operator()<std::decay_t<T&&>>()) dispatch_foo::operator()(T&&) const
    
    template arguments: [
      'T' = char
      '1' = void
    ]
    repro.cpp:26:38
    using foo_t = decltype(dispatch_foo{}(std::declval<T>())); 
                                         ^
      error: repro.cpp:18:46
      call to member function int dispatch_foo::operator()() const without an object argument
        function declared at repro.cpp:9:3
          -> decltype(operator()<std::decay_t<T&&>>()) 
                                                   ^

clang compiles this program without error:

$ clang -I. -std=c++14 repro.cpp 

Compiler details:

$ circle --version
circle version 1.0.0-134
  Circle public preview build 134
  Built Sep 25 2021 16:55:11
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax
jhoberock@jhoberock-dt:~/dev/git/coord$ clang --version
clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

Feature request: implicit `noexcept(auto)`

One of the problems with C++ are the "incorrect" defaults (eg mutable variables by default instead of mutable when needed). One of these defaults is missing noexcept(condition) on function bodies being evaluated as noexcept(false) instead of automatically deducing based on the function's body. Consider the following example : judging by the body of f, it is noexcept, but the check decides it is rather noexcept(false) (hence the program returns 0).
I propose the following changes:

Functions without noexcept in their bodies are considered to be non-throwing whether the operations on the body of the functions are non-throwing, otherwise (if noexcept(cond) is specified) the function is declared to throw whether the condition is false. In cases of conditional branches (if/while) each branch contributes to the exception specification of the function, unless the branch is evaluated at compile-time (eg. on if constexpr) in which only the chosen branch contributes (obviously). The same rules apply to lambdas and operator overloads.

These changes allow for more ergonomic and optimized code. Consider the following examples:

  1. The LIFT macro
    Previously
#define LIFT(foo) \
  [](auto&&... x) \
    noexcept(noexcept(foo(std::forward<decltype(x)>(x)...))) \
   -> decltype(foo(std::forward<decltype(x)>(x)...)) \
  { return foo(std::forward<decltype(x)>(x)...); }

With noexcept(auto)

#define LIFT(foo) \
  [](auto&&... x) \
   /* automatic deduction of exception guarantees */
   -> decltype(foo(std::forward<decltype(x)>(x)...)) \
  { return foo(std::forward<decltype(x)>(x)...); }

This also applies to any other lambda object and/or function, allowing for a terser syntax.

  1. Generic code
    Consider overload 3) from here:
    Previously
constexpr vector& operator=( std::initializer_list<T> ilist ) noexcept(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
|| std::allocator_traits<Allocator>::is_always_equal::value) { /* ... */ }

With noexcept(auto)

constexpr vector& operator=( std::initializer_list<T> ilist ) { /* ... */ }

As you may have noticed from the examples the feature allows for templated code that is both easier to write and maintain, making metaprogramming more approachable to a wider range of programmers. There are also other cases where the feature would be useful. For example, given the compiler will automatically deduce the exception specification, C functions can be assumed exception free leading to more optimizations.

PS: Please note that even though the feature name is noexcept(auto), there is no proposal to add such syntax. Instead, it refers to the ability of the compiler to deduce the exception specification of a function.

circle: "function expects 1 or more arguments" in abbreviated function template

The following program

void foo(auto&&...){}

int main()
{
  foo();
  return 0;
}

Causes circle to emit the error message

$ circle -std=c++20 repro.cpp 
error: repro.cpp:5:6
no viable candidates in call to 'foo'
  foo(); 
     ^
  candidate: void foo(0&&)
  repro.cpp:1:6
  void foo(auto&&...){} 
       ^
    error: invalid argument count
    function expects 1 or more arguments

Clang and g++ accept the program:

$ clang -std=c++20 repro.cpp 
$ g++ -std=c++2a -fconcepts repro.cpp 

Compiler details:

$ circle --version ; echo ; clang --version ; echo ; g++ --version
circle version 1.0.0-137
  Circle public preview build 137
  Built Oct  7 2021 23:28:38
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Segmentation fault when template template parameter's default is a template member of a template

The program

template<class T>
struct has_member_template
{
  template<class... Types>
  using type = int;
};

template<class T, template<class...> class Template = has_member_template<T>::template type>
using foo_result_t = int;

template<class T>
foo_result_t<T> foo()
{
  return {};
}

int main()
{
  foo<int>();

  return 0;
}

Causes a segmentation fault when compiled with circle:

$ ~/Desktop/circle/circle repro.cpp 
Segmentation fault (core dumped)

Compiler details:

$ circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 11:04:48
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

circle: "expected a template as default of template-template parameter" when default is a member template

The following program

template<class...>
struct not_a_member_template {};

template<class T>
struct foo
{
  template<class... Types>
  using member_template = int;
};


// XXX error
template<class T, template<class...> class Template = foo<T>::template member_template>
using bar = int;

// XXX compiles OK
template<class T, template<class...> class Template = not_a_member_template>
using bar = int;


int main()
{
  return 0;
}

Causes circle to emit the following error message:

$ circle -I. repro.cpp 
error: repro.cpp:13:55
expected a template as default of template-template parameter
template<class T, template<class...> class Template = foo<T>::template member_template> 

Compiler details:

$ ~/Desktop/circle/circle --version
circle version 1.0.0-135
  Circle public preview build 135
  Built Sep 26 2021 22:32:16
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

pragma pop_macro leaves macro defined

The following program:

#ifndef INCLUDE_LEVEL
#  define INCLUDE_LEVEL 0
#else
#  pragma push_macro("INCLUDE_LEVEL")
#  define INCLUDE_LEVEL 1
#endif


// at this point the macro stack is:
//
// INCLUDE_LEVEL = 0


#ifndef INCLUDE_LEVEL
#  define INCLUDE_LEVEL 0
#else
#  pragma push_macro("INCLUDE_LEVEL")
#  define INCLUDE_LEVEL 1
#endif


// at this point the macro stack is:
//
// INCLUDE_LEVEL = 1
// INCLUDE_LEVEL = 0


#if INCLUDE_LEVEL == 1
#  pragma pop_macro("INCLUDE_LEVEL")
#else
#  undef INCLUDE_LEVEL
#endif


// at this point the macro stack is:
//
// INCLUDE_LEVEL = 0


#if INCLUDE_LEVEL == 1
#  pragma pop_macro("INCLUDE_LEVEL")
#else
#  undef INCLUDE_LEVEL
#endif


// at this point the macro stack should be empty, and INCLUDE_LEVEL should not be defined


#ifdef INCLUDE_LEVEL
#  error INCLUDE_LEVEL defined in client code.
#endif


int main()
{
  return 0;
}

Causes circle to hit the #error case:

$ circle -I. repro.cpp 
preprocessor: repro.cpp:51:9
#error: 'INCLUDE_LEVEL defined in client code.'

clang compiles without error, but g++ complains about macro redefinition:

$ g++ -I. repro.cpp 
repro.cpp:18: warning: "INCLUDE_LEVEL" redefined
   18 | #  define INCLUDE_LEVEL 1
      | 
repro.cpp:2: note: this is the location of the previous definition
    2 | #  define INCLUDE_LEVEL 0

I'm not sure whether clang or g++'s behavior is more correct.

Compiler details:

$ circle --version ; echo ; clang --version ; echo ; g++ --version
circle version 1.0.0-135
  Circle public preview build 135
  Built Sep 26 2021 22:32:16
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

clang version 10.0.0-4ubuntu1 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

circle: "expected value in conditional" upon #if __CUDACC__

The program

#include <iostream>

int main()
{
#if __CUDACC__
  std::cout << "__CUDACC__ defined" << std::endl;
#endif

  return 0;
}

Causes circle to emit the following error message:

$ circle --cuda-path=/usr/local/cuda -sm_50 repro.cu 
preprocessor: repro.cu:5:5
expected value in conditional

Compiler details:

$ circle --version
circle version 1.0.0-136
  Circle public preview build 136
  Built Sep 27 2021 23:42:52
  (c) 2021 Sean Baxter
  https://www.circle-lang.org/
  Twitter: @seanbax

cling based C++ as scripting language / hot code reload

cling based C++ as scripting language / hot code reload
Why? Able to run C++ script in runtime or compile it for max speed ( as in example https://github.com/derofim/cling-cmake )

HOT code reload
possible approaches:

store app state
fix cling undo for files
https://root-forum.cern.ch/t/loading-unloading-class-as-interpreted-macro-in-cling-multiple-times/32976/2

execute cling code to change callbacks & variables
nested cling::Interpreter with multiple cling::MetaProcessor
IDK how to do it, but you can create child cling::Interpreter

Consider adding a "cu" option to the -x language flag

nvcc recognizes cu as an option for the -x command line language flag to indicate that the source file should be treated as CUDA code. It would be helpful if circle recognized this option as well to aid in porting old code bases.

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.