jondgoodwin / cone Goto Github PK
View Code? Open in Web Editor NEWCone Programming Language
License: MIT License
Cone Programming Language
License: MIT License
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:
LLVMDIR
environment variable to the LLVM 7.0.1 directory.Cone.vcxproj
and retargeted it for VS2019 and my current Windows SDK.conestd.vcxproj
-> retargeted for VS2019 and my current Windows SDK.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?
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...
print <- true
doesn’t output anything.
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.
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?
It would be nice if this page could contain a couple of examples or snippets: https://cone.jondgoodwin.com/memory.html
This compiles but then we can't do anything :
mut M[3,4;f32]
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.
"Error 1019: The name Text does not refer to a declared name"
I'm just trying to follow the docs!
http://cone.jondgoodwin.com/coneref/reftypesafe.html
This fails :
if { mut x = 3; x } == 3:
print <- "hello"
The code snippet in section '<-' Prefix Operator of Reference page https://cone.jondgoodwin.com/coneref/refblock.html, simplified to
mut numbers = [1f]
with &mut numbers:
<- 3.4f
gives the errors:
Error 1034: Cannot borrow mutable reference to this.
--> <- 3.4f
^--- test4.cone:6:5
Error 1025: Invalid operation on a reference.
--> <- 3.4f
^--- test4.cone:6:5
Unsuccessful compile: 2 errors, 0 warnings
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 :)
This fails
print <- "x", 3u32
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.
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.
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?
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.
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)
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).
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.
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.)
Run the code inline in the docs, like they do for Go+ (a run button is displayed when the mouse pointer hovers over the code snippets) :
https://tutorial.goplus.org/hello-world
Copy and paste in a new tab opened with the playground would be a start.
I have experienced some problems with the play page on the website. (https://cone.jondgoodwin.com/play/index.html)
The hello, world
given as a start gives an error (I don't really know how the syntax is because I just heard of it).
Secondly, I am not able to change the theme and editor.
typedef Vector [10;f32]
Any typedef really, but the doc says it's been implemented, like:
typedef myInt i32
This fails saying x
is not defined
mut x i32
fn main():
x = 7
but this shows that the x
is seen by the compiler because he complains of type inadequacy in that case
mut x i32
fn main():
x = 7.4
Sometimes I get this :
Compile finished in 1.84467e+10 sec
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
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.
It give me the error saying that I am not conected to internet when I try to create a new gist
This fails
print <- &fn(x i32) i32 { 2*x } (3)
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.
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:
Global arrays are not accessible if not initialized, but the same is not true for local arrays :
https://is.gd/ngHQ6M
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
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!
this fails :
imm x = [1, 2, 6][2]
Hi! Cone seems a pretty interesting language and I would like to make some questions if you don't mind.
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!
each i in 0 < N
should cast the 0 to the type of N when possible, because by default it is u32. So literals should be cast properly, as needed.
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.
Can't put this in global scope
imm numbers [3; i32] = [3, 4, 5]
import stdio::*
struct Matrix:
mut arr [4;f32]
fn `[]`(n usize) f32, Bool:
if n < 4:
arr[n], true
else:
0f, false
fn main() {}
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?
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.
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
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)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.