egranata / cplusminus Goto Github PK
View Code? Open in Web Editor NEWThe C± Language
License: Apache License 2.0
The C± Language
License: Apache License 2.0
Introduce a way to check a pointer for null. This can be done by converting a pointer to integer, or making a pointer a valid boolean expression with the implicit != 0
semantics, or by introducing an explicit is_null
helper API
StatementBuilder
and ExpressionBuilder
should contain an inkwell Builder instance instead of needing one passed in to every function.
To make this work safely, first one should store the "obvious" builder instance at creation time, and make sure that a different Builder argument is never passed in to a function, and only then delete the Builder argument.
If it turns out that passing around different inkwell Builders makes sense, it should be replaced by creating a new compiler Builder object with the updated payload
Describe the bug
Types should have some form of metadata attached to them
Additional context
Right now, we carry around pointers to the user and system deallocators for each object that needs one, because there is nowhere else to store them but the object itself. However, these names could be trivially inferred based upon the type's name, and also stored based on the type itself to save instance space. Provide some form of metadata (at least a name and the deallocators) at least for reference types, such that we can optimize some of the code managing the lifetime of these
anyref
would be the type of an arbitrary reference type object. The advantage is that all such types have identical size (one pointer) and metadata can be used to decide questions like "are you an instance of X
vs. Y
concrete types?" and "how do I free this memory?"
Having such a type would make it possible to build some basic (if unsafe) data structures without needing generics in the core language
For a type T
, it should just be possible to say T(...)
to create an instance. This could be done by creating implicit overloaded functions (one per init
of the type) of the same name, and removing alloc
from the grammar so it cannot be used in program code
There is no way to compare value type instances for equality, e.g.
val type VT {
x: int64,
}
func main() ret int32 {
let v1 = alloc VT{x:1};
let v2 = alloc VT{x:2};
let eq = v1 == v2;
let t1 = {1,2,3};
let t2 = {3,4,5};
let eq = t2 == t1;
return 0;
}
the comparisons will fail:
error: type mismatch in expression
┌─ test.cpm:23:14
│
23 │ let eq = v1 == v2;
│ ^^^^^^^^
error: invalid expression
┌─ test.cpm:23:14
│
23 │ let eq = v1 == v2;
│ ^^^^^^^^
error: type mismatch in expression
┌─ test.cpm:28:14
│
28 │ let eq = t2 == t1;
│ ^^^^^^^^
error: invalid expression
┌─ test.cpm:28:14
│
28 │ let eq = t2 == t1;
│ ^^^^^^^^
There is no definition of equality for value types, either implicit by bitwise comparison or explicit by user defined comparator
When applying any kind of make_arg_compat
conversion, there should be at least two pieces of information returned:
This would allow two things:
(*) for example say there is
ref type T {}
impl T {
func foo(x: int32) ret int64 {
return 1;
}
func foo(x: int64) ret int64 {
return 2;
}
}
If we wanted to add implicit integer widening, a call of the form
let n: int32 = 3;
t->foo(n);
would suddenly be ambiguous because it could result in either a call to the first overload (at 0 cost) or a call to the second (at 1 cost)
It is possible that this kind of widening or other implicit compatibility transformations may render a call ambiguous with multiple overloads of equal cost, and so there should always be a way to disambiguate, e.g. x as T
may be that syntax and not permit any additional transforms?
Describe the bug
Do not emit declared but never used warnings for the self
value in methods
To Reproduce
Compiler version: top of tree
Source program:
ref type T {
init() {},
dealloc {},
func foo() ret int32 {
return 0;
}
}
func main() ret int32 {
return 0;
}
Command line: cargo run -- test.cpm
Expected behavior
This program compiles and runs cleanly
Actual behavior
Warnings are emitted:
warning: variable self was declared but never used
┌─ test.cpm:17:5
│
17 │ dealloc {},
│ ^^^^^^^^^^
warning: variable self was declared but never used
┌─ test.cpm:16:5
│
16 │ init() {},
│ ^^^^^^^^^
warning: variable self was declared but never used
┌─ test.cpm:18:5
│
18 │ ╭ func foo() ret int32 {
19 │ │ return 0;
20 │ │ }
│ ╰─────^
When defining a type, it should be possible to define methods as well as member variables and helpers, e.g.
type foo {
x: int64,
y: int64,
func add() ret int64 {
return self.x + self.y;
}
}
should be a viable syntax identical to
type foo {
x: int64,
y: int64,
}
impl foo {
func add() ret int64 {
return self.x + self.y;
}
}
Describe the bug
The self
argument for a value type method is not transparently dereferenced
To Reproduce
Compiler version: top of tree
Source program:
val type VT {
x: int64,
}
func do_something(vt: VT) ret int64 {
return vt.x;
}
impl VT {
func foo() ret int64 {
return 123 + do_something(self);
}
}
func main() ret int32 {
let vt = alloc VT{x:321};
let n = vt->foo();
assert n == 444;
return 0;
}
Command line: cargo run -- test.cpm
Expected behavior
The program exits cleanly
Actual behavior
Compilation errors:
error: type mismatch in expression: expected VT
┌─ test.cpm:25:35
│
25 │ return 123 + do_something(self);
│ ^^^^
error: type mismatch in expression: expected callable function
┌─ test.cpm:25:22
│
25 │ return 123 + do_something(self);
│ ^^^^^^^^^^^^^^^^^^
error: type mismatch in expression
┌─ test.cpm:25:16
│
25 │ return 123 + do_something(self);
│ ^^^^^^^^^^^^^^^^^^^^^^^^
error: invalid expression
┌─ test.cpm:25:16
│
25 │ return 123 + do_something(self);
│ ^^^^^^^^^^^^^^^^^^^^^^^^
Additional context
This is because the self
argument is a *VT
, but that should be invisible to the user
Describe the bug
Support for debug information is missing
Expected behavior
There is enough debug information present that basic debug workflows are supported, including:
Actual behavior
No debug information is emitted, a debugger can only step through machine code and rely on symbol table information
Numbers are treated by default as signed, and currently there are no builtin operators for unsigned operators. Introduce such operators, e.g. u/
for unsigned division and so on. This should be unambiguous syntactically
Describe the bug
The codebase expects main to return int64 in some cases and int32 in others. int32 should be the return type of main as this is the default convention on most everything else
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.