GithubHelp home page GithubHelp logo

jondgoodwin / cone Goto Github PK

View Code? Open in Web Editor NEW
506.0 506.0 17.0 23.97 MB

Cone Programming Language

License: MIT License

C 99.34% CMake 0.66%
compiler concurrency cone memory-management programming-language systems-language type-safety web3d webassembly

cone's People

Contributors

codenoid avatar ivo-balbaert avatar jondgoodwin avatar lerno avatar madmann91 avatar meai1 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

cone's Issues

A coule of questions

Hi! Cone seems a pretty interesting language and I would like to make some questions if you don't mind.

  1. What's the compilation speed of Cone compared to other compilers like GCC, LDC, Rust, Vox, TCC etc. I'm talking about compilation with full optimizations on.
  2. What's the runtime performance compared to "gcc -O3"? How many times slower in the worse, average and best cases? Well maybe worse case is enough...
  3. How would you call the future of Cone? Do you plan on supporting the project and make it into a fully industry scale language that will be used be millions or you may abandon it sooner or later?
  4. Cone targets 3D and promotes how good it is in the 3D scene, does this mean that Cone will be weak in general tasks like Desktop apps, embedded, webapps (non-3D), AI etc.? Do you recommend against the use of Cone in everything non-3D?

Don't get my wrong, I really care about all that, it's not some random questions I made to waste your time. Of course, feel free to not answer to any of them or even to all of them and close my issue if you want. In that case, I wish you good luck with the project!

Segmentation fault in printing nil

The following code snippet segfaults at execution. Instead, it should generate an error message. It should be illegal to assign nil to dessert, and print <- nil should be a "function not found" error.

import stdio::*

imm hello = "Hello"

fn main():
  mut dessert = jello(hello)
  print <- dessert // <-- Segmentation fault

fn jello(mut saying [5; u8]):
  saying = "jello"
  saying

Why a version of LLVM so old is used?

Will it not work with a more resent version of LLVM? I can't get the LLVM version 7. Well I can but I have to compile it and It's a pain in the ass to compile LLVM...

Using a conditional expression with a non-boolean value

The Reference (https://cone.jondgoodwin.com/coneref/refif.html) states that in a conditional expression the integer number 0, a Null value, and false all evaluate to false; ll other values evaluate to true.

if false: and if 0: work

What is the value of Null?

if Null: a = a + 1

produces the Error 1023: Macro expects arguments to be provided
--> if Null: a = a + 1
^--- test.cone:5:6
conec: /home/ivo/cone/src/c-compiler/ir/iexp.c:79: iexpCoerce: Assertion `isExpNode(*from)' failed.
Aborted

null is also not recognized.

Assuming nil is the Null value, this gives the error:
Error 1013: Conditional expression must be coercible to boolean value.
--> if nil: a = a + 1
^--- test.cone:5:6
Unsuccessful compile: 1 errors, 0 warnings
If nil is not the Null value, what is?

Using non-null values:

This works:

mut a = 0
if 42: a = a + 1
print <- a, "\n"  // a is 1

These also work:

 if 3.14: a = a + 1
 if 'a': a = a + 1

However neither of the following work, and all produce: Error 1013: Conditional expression must be coercible to boolean value.
if "hello": (used on: https://cone.jondgoodwin.com/coneref/refif.html)
if "hello" == "":
if "hello" != "":
if not("hello" == ""):
if [1, 2]:

It seems at this moment only numbers and characters are coercible to booleans?

Export public symbols to WebAssembly by default

As we've discussed on irc, it is possible to export them all through:

conec main.cone --wasm && wasm-ld ./main.wasm -o main.wasm --no-entry --import-memory --allow-undefined-file=libc.imports --export-all

I check whether the output has generated exported symbols by using the wasm2wat tool, compiled from here: https://github.com/WebAssembly/wabt

But the idea is to export only public functions / globals, not everything - so that's more like a hack.

I did some research on this, this is probably the best link that explains it:
https://lld.llvm.org/WebAssembly.html#imports-and-exports

When building a shared library any symbols marked as visibility=default will be exported. When building an executable, only the entry point and symbols flagged as WASM_SYMBOL_EXPORTED are exported by default. In LLVM the WASM_SYMBOL_EXPORTED flag is applied to any symbol in the llvm.used list which corresponds to attribute((used)) in C/C++ sources.
In addition, symbols can be exported via the linker command line using --export.
Finally, just like with native ELF linker the --export-dynamic flag can be used to export symbol in the executable which are marked as visibility=default.

LLVM LangRef.rst states the particulars on how to do it (but only in LLVM IL unfortunately)

The ``@llvm.used`` global is an array which has
:ref:`appending linkage <linkage_appending>`. This array contains a list of
pointers to named global variables, functions and aliases which may optionally
have a pointer cast formed of bitcast or getelementptr. For example, a legal
use of it is:

.. code-block:: llvm

    @X = global i8 4
    @Y = global i32 123

    @llvm.used = appending global [2 x i8*] [
       i8* @X,
       i8* bitcast (i32* @Y to i8*)
    ], section "llvm.metadata"

If a symbol appears in the ``@llvm.used`` list, then the compiler, assembler,
and linker are required to treat the symbol as if there is a reference to the
symbol that it cannot see (which is why they have to be named). For example, if
a variable has internal linkage and no references other than that from the
``@llvm.used`` list, it cannot be deleted. This is commonly used to represent
references from inline asms and other things the compiler cannot "see", and
corresponds to "``attribute((used))``" in GNU C.

This is how far I made it:


        LLVMTypeRef arrType = LLVMArrayType(LLVMPointerType(func_type, LLVMGetPointerAddressSpace(func_type)), 1);
        LLVMValueRef arrInstance = LLVMAddGlobal(gen->module, arrType,"llvm.used");
        LLVMSetSection(arrInstance, "llvm.metadata");
        LLVMSetLinkage(arrInstance, LLVMAppendingLinkage);

I dont know if this comes close but I think it might. It's just trying to create this global array of pointers that was described in the .rst doc above. I dont know how to use the C API to populate the array with a pointer to the function.

Error when compiling Hello World - example

I successfully installed the current Cone on Ubuntu 20 (inside WSL2).

The following Hello World example:

import stdio

fn main():
  print <- "Hello world!"

runs fine within Cone's PlayGround, but when I try to compile it on my machine it errors out:

$ conec hello_world.cone
Error 1019: The name print does not refer to a declared name
--> print <- "Hello world!"
^--- hello_world.cone:4:3
Unsuccessful compile: 1 errors, 0 warnings

Is there any additional step I need to fix this? Thanks!

Pattern-matching example errors out

The 1st example on page https://cone.jondgoodwin.com/coneref/refmatch.html

import stdio::*

fn main():
  print <- power(3, 2) 

fn power(n i32, pow i32) i32:
  match pow:
    0: 1
    1: n
    2: n * n
    _: -1

Produces (instead of 9) the errors:
Error 1013: if requires an 'else' clause (or exhaustive matches) to return a value
--> match pow:
^--- pattern_match.cone:10:3
Error 1013: Expression does not match expected type.
--> match pow:
^--- pattern_match.cone:10:3
Unsuccessful compile: 2 errors, 0 warnings

I can't make match of any of the errors given, none seem to be appropriate: no if/else , _ is exhaustive, all types are i32.
Is there another way (syntax) to make this work?

What is the language status?

Hi,

I find the design of Cone to be very appealing. Yet, it seems that the the core language is not implemented yet. I think stating what features are currently implemented (maybe using boxes in the Readme like [ ] and [x]) would help people know if they want to dig Cone right away of wait a little bit.

What do you think?

Implicit self parameter is not treated as mut

The following code compiles:

struct Test:
  n u32

  fn inca(a u32):
    n += a

but this slight variation in inca:

  fn inca(a u32):
    n = a + 1

gives the error:

Error 1017: You do not have permission to modify lval
--> n = a + 1
^--- test.cone:5:5
Unsuccessful compile: 1 errors, 0 warnings

mut n doesn't change this behavior

The following code compiles:

struct Test:
n u32

fn inca(mut self Test, a u32):
n = a + 1

Incorrect error message ("one-off")

The following code snippet:

import stdio::*

fn main():
  mut m = {
    imm n = 3.0
    6 + n     
  }
  print <- m

gives the error message

Error 1025: No method/field named <- found that matches the call's arguments.
--> print <- m
^--- test.cone:8:9
Unsuccessful compile: 1 errors, 0 warnings

This seems a false error message, while the real problem is probably that + does not handle an integer and a float. Indeed the code works with 6 + i32[n], or when both numbers are integers or floats.

Strange error in if expression using +=

This code

fn main():
      mut a = 0
      if 42: a += 1

gives the Error 1048: This variable has not been initialized. There is no value to use.
-->
^--- test.cone:6:1
Unsuccessful compile: 1 errors, 0 warnings

However rewriting it as: if 42: a = a + 1
makes it work.

[SUGGESTION] Miragrating to the latest LLVM version should be the biggest and only priority

I don't have a lot to say actually. As I had issues to install LLVM7, I think that the top priority would be to migrate to LLVM 12 (latest stable version at the time of writing) and freeze anything else. I believe other people will have the same problem as me so having the users to be able to use the language should be the most import thing imo. I know it will take some time but you'll have to do it some time anyway so at least do it now and continue with anything else after that.

Of course this is just my opinion because I like Cone and I want to try it out. The final choice is yours! And if you decide against it, I'll happily wait :)

Suggestion: Add better function/block termination

Overall goal: More safety and less ambiguous code, faster reading of code, not just faster typing.

Point 1 Remove implicit returns, require writing 'return'

This is the julia syntax that I consider ideal:

function loop_over_global()
    return 1
end

This is Cone's pythony syntax right now (remember, Julia was created primarily to replace Python as a better alternative)

fn loop_over_global() i32
    1

I mean can you honestly say that the second is easier and less ambiguous to read?

Point 2 Require writing 'end' to end blocks like functions or loops

Here is a julia loop:

for i in x::Vector{Float64}
        s += i
end

The problem I have with python like identation: How can I be sure that I copy pasted some piece of code correctly or not? I have to check every single line if it was pasted with the right identation. This could introduce errors of an absolutely nightmare kind where oh oops, one line of 2000 didnt copy paste correctly and the variable at the end of a loop went outside of the loop which now changes the behavior of the loop or the rest of the program in silent ways. I mean this is C undefined behavior kinds of dangerous.

So we can see that even for data scientists who arguably want to write one-off, quick and dirty code.. the julia authors felt like moving away from Python syntax was best and to make these changes.

Shortened declaration syntax not yet working

On page reffunc.html: in the example with the ceil() function the variables to get the 2 return values are declared as:

mut a,b = ceil(8)

However this doesn't work yet, neither for imm.

The following program:

fn main():
  mut a, b = ceil(8)   
  a, b = ceil(3)       
  
fn ceil(x i32) i32, i32:
  if x > 6:
    return x, 6
  x, x

Error 1003: Statement finished? Expected semicolon or end of line.
--> mut a, b = ceil(8)
^--- functions.cone:18:8
Error 1006: Invalid term: expected name, literal, etc.
--> mut a, b = ceil(8)
^--- functions.cone:18:8

Workaround:
It works if every variable is declared separately.

mut a i32; mut b i32
a, b = ceil(8)

Opening playground in new browser provides broken Hello World.

Opening http://cone.jondgoodwin.com/play/index.html in a browser with a blank cache pops up the following program:

// Your program goes here...
extern fn print(str *u8)

fn main()
  print("Hello world!")

as seen at

Note the lack of a : after fn main() at the cursor in the screenshot.

Hitting the "Run" button yields:

Error 1040: Function/method must be implemented.
 --> fn main()
     ^--- work/test.cone:4:1
Unsuccessful compile: 1 errors, 0 warnings

Compilation failed.

If I choose "Hello, World!" from the dropdown I get a version with the : that runs fine and which differs in its leading comment: // Hello World!

Compile finished in 0.0041467 sec (155 kb). 0 warnings detected

Hello world!

Program ended.

Once I've selected the working version from the dropdown, reloading the page will restart with the version with the colon.

Shorter syntax for declaring variables

Golang made a genius move by removing the 'var' in favor of :=
It makes all code shorter and more python-y
I propose that Cone makes the same move and does something like this:

imm x = 5 becomes x ::= 5
mut x = 5 becomes x := 5

It's not just the amount of characters that is at play here. Reading a file from top to bottom is much easier when the name of variables is right there on the leftmost side. Consider this: imm and mut are in reality metadata for the compiler. Sure, it's useful to know this when reading code but the real information we usually want to know as programmers when we scan over some code visually with our eyes is not all this metadata stuff. It's the actual names of variables, functions, constructs. This syntax makes that scanning easier and faster for humans.

If statement after an expression does not work

At several places the Reference uses an if statement after an expression, for example:

https://cone.jondgoodwin.com/coneref/refbasics.html
return 0d if nterms <= 0

https://cone.jondgoodwin.com/coneref/refif.html
// This statement will never execute
a += 1 if 0 // since 0 evaluates to false

This doesn't work in the current state of the compiler.
As a simple test case, this program

fn main():
  mut a = 0
  a += 1 if 42

gives the following errors:

Error 1003: Statement finished? Expected semicolon or end of line.
--> a += 1 if 42
^--- test5.cone:5:10
Error 1004: Expected ':' or '{' to start a block
-->
^--- test5.cone:6:1
Error 1005: Expected end of block (e.g., '}')
-->
^--- test5.cone:6:1
Unsuccessful compile: 3 errors, 0 warnings

If writing the last line as a += 1 if 42: (which doesn't seem logical either) only error 1003 remains.

Perhaps this feature has been deprecated and it will not be supported anymore.
In that case only the Reference pages have to be adapted (I can do a PR if wanted).

Better error message needed "expecting semicolon"

Error 1003: Expected semicolon - skipping forward to find it
--> mut a = &gc Point(1., 2.)

I dont have a Point type in this sample but it doesnt complain about that, instead it only complains about a semicolon? Weird.

fn main()
  mut a = &gc Point(1., 2.)

+ operator called as a method in backticks does not work or is not implemented

The page refexpr.html in the Cone reference mentions:

The arithmetic operators introduced earlier (e.g., + for add) are implemented under the covers using number type methods:
// The method name equivalent for the + operator is +
// The method name is enclosed in backticks since it includes punctuation
3+4 // is actually: 3.+(4)

However the following code snippet:

   print <- 3.`+`(4), "\n"

gives the error:

Error 1003: Statement finished? Expected semicolon or end of line.
--> print <- 3.+(4), "\n"
^--- test.cone:5:14
Unsuccessful compile: 1 errors, 0 warnings

No obvious workaround: parentheses does not help, neither does storing it in a variable.

Tested on both Windows 11 and Ubuntu 20 with latest Cone compiler version.

Compilation only outputs .o file, no errors shown

Problem:
Compilation outputs no executable binary, only .o

Description:
I dont see any option in the --help to specify a different type of output so I assume it's an error. I searched through all subfolders but there is no hello or a.out file.
./conec ./hello.cone

extern fn print(str *u8)

fn main()
  print("HI")

Enabling stronger logging shows nothing:

[pc@localhost cone]$ ./conec -V=4 hello.cone
Compile finished in 0.000000 sec (84 kb). 0 warnings detected

Possible source:
I compiled LLVM with different options because my output was huge, (>20GB) and I dont have that much disk space. These are my options: (also this is using gcc 8.1)
cmake -DCMAKE_INSTALL_PREFIX="/home/pc/workarea/experiments/llvm-7" -DCMAKE_BUILD_TYPE="MinSizeRel" -DLLVM_TARGETS_TO_BUILD="host" -DLLVM_BUILD_TOOLS="NO" -DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly ..

strace file if you are interested:
strace.txt

Even if this is somehow my fault because I used other options, point is that I need to know why. Cone itself compiled fine after all.

uninitialized imm variable can't be assigned in branches

The top example in http://cone.jondgoodwin.com/coneref/refif.html shows:

fn abs(x i32) i32
  imm result i32;
  if x < 0
    result = -x
  else
    result = x
  result

but this errors with:

Error 1017: You do not have permission to modify lval
 -->     result = -x
         ^--- work/test.cone:4:5
Error 1017: You do not have permission to modify lval
 -->     result = x
         ^--- work/test.cone:6:5
Unsuccessful compile: 2 errors, 0 warnings

Changing result to mut makes this example work.

Can't create a gist

It give me the error saying that I am not conected to internet when I try to create a new gist

Add support for typed array size

This should be possible :

mut arr [10u8 ; f32]

in order to add performance when arrays are not large, so only need u8 or similar type for the size.

Same for mut arr [10u16, 25u8;f32] to allow mixing types

Windows build instructions?

I'm a bit confused about how to build this properly (I don't use Visual Studio often). I currently have VS2019.

Here are the steps I took:

  • Downloaded LLVM 7.0.1 Windows x64 binary.
  • Set LLVMDIR environment variable to the LLVM 7.0.1 directory.
  • Opened Cone.vcxproj and retargeted it for VS2019 and my current Windows SDK.
  • File -> Add -> Existing project... -> conestd.vcxproj -> retargeted for VS2019 and my current Windows SDK.
  • Set it to x64 instead of x86, but left it on Debug.
  • Right-click -> Build Solution

I got this error:

LINK : fatal error LNK1561: entry point must be defined

It's the conestd project that's throwing this error. Am I not supposed to be using that one?

EDIT: I also see that I am going to have to build LLVM from source. There's no chance that it works with LLVM 9, is there? I've already got that one built from source.

If not, which flags would I need on Windows to ensure that it works with Cone?

Delayed initialization code doesn't seem to work for an immutable value

The following code (mentioned in the Reference)
doesn't work:

fn main():
  imm height f32
  height = 1.86

It gives the compiler error:

Error 1017: You do not have permission to modify lval
--> height = 1.86
^--- test.cone:3:3
Unsuccessful compile: 1 errors, 0 warnings
This compile error occurs for the current Cone version and in the playground.

This works for a mutable (mut) value.
Is there another way to delay initialization of an immutable value?

(Was also mentioned in issue #1)

Show example on how to implement C function calls

Interop with C will probably be the primary way to get real world usefulness out of Cone, so that should be documented in my opinion.
How do I read a file?
How do I write to a socket?
How do I walk a directory tree?
etc.
So this is probably done by writing a wrapper around libc/muslc, right?

General usecases:

  1. pass data or functions into C, get data or functions back
  2. make those functions you pass in callable from either side

`typedef` fails

typedef Vector [10;f32]
Any typedef really, but the doc says it's been implemented, like:
typedef myInt i32

Overloading does not work for operator methods

The following code:

struct Point:
  x f64
  y f64
  
  // Subtract two points
  // A `-` method implements the binary subtract ('-') operator
  fn `-`(pt2) Point:
    Point[pt2.x - x, pt2.y - y]

  // Overloading: unary operator
  fn `-`() Point:
    Point[-x, -y]
  
fn main():
  mut pt1 = Point[3d, 0d]
  imm pi1m = -pt1

gives the following error at compilation:

Error 1022: Function call requires more arguments than specified
--> imm pi1m = -pt1 // Error 1022: Function call requires more arguments than specified
^--- test.cone:16:14
Unsuccessful compile: 1 errors, 0 warnings

It seems that the subtract definition of - is called here, instead of the unary - definition.
Perhaps overloading does not work for operator methods.

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.