arian / metac Goto Github PK
View Code? Open in Web Editor NEWA MetaC to C compiler using Spoofax
License: Apache License 2.0
A MetaC to C compiler using Spoofax
License: Apache License 2.0
Instead of writing
MaybeError<int32> safe_divide(int32 a, int32 b) {
if (b == 0) return Error();
else return (a / b);
}
You should be able to write
MaybeError<int32> safe_divide(int32 a, int32 b) {
return (b == 0) ? Error() : (a / b);
}
For example
statemachine X {
init start;
event foo(int32);
state start {}
}
Here the event foo
accepts some arguments, but it cannot be used inside the statemachine, as it doesn't have name.
The parameter is parsed/desugard to a FunDefinitionParameter/1
node. If that happens to be inside an Event/3
, it should produce a warning for the programmer.
Currently unions and structs of the following form are not correctly desugared to TypedefDeclarations.
typedef struct {
uint8 success;
volatile int8 value;
} __MaybeError_f;
For example
void f() {
(MaybeError<int, int>) 1;
}
should not be valid.
int f() { return 1; }
signed int a = f();
generates a false error.
Incompatible types when initializing type Signed using type Int32
In the example of
void test_pointer_bitfields() {
uint32 a_;
A *a = &a_;
(*a).a = 1;
assert((*a).a == 1);
puts("pointer bitfields variable successful\n");
}
(*a).a
has to be used. In idiomatic C, you would use a->a
instead. Unfortunately the extra analysis is not done for PointerField
yet.
For example when doing:
int x = (2 + 4) % 2;
The generated code is:
int x = 2 + 4 % 2;
which has a different meaning.
Having this code
int a[100];
And generating the C code again, the output is:
int a[];
Instead it should generate the cod with the array size
If you #include
a header file, spoofax will import defined functions/variables from that other module. Using desugaring this works already, but the other file should be opened in Eclipse to fully resolve the references.
For example
MaybeError<int32,uint8> f(uint8 a) {
if (a == 0) return Error(1 + 2);
return a;
}
void h() {
attempt[a] {
uint8 x ?= f(1);
} fail (uint8 a) {
a;
}
}
outputs
typedef struct {
unsigned char success;
union {
signed int value;
unsigned char error;
} result;
} __MaybeError_f;
unsigned char f (__MaybeError_f *__maybeErrorReturn_f, unsigned char a) {
if (a == 0) return (
__maybeErrorReturn_f->result.error = 1 + 2,
__maybeErrorReturn_f->success = 0);
return (
__maybeErrorReturn_f->result.value = a,
__maybeErrorReturn_f->success = 1);
}
void h () {
unsigned char attempt_a_1_a;
{
__MaybeError_f __maybe_x;
f(&__maybe_x, 1);
if (!__maybe_x.success) {
attempt_a_1_a = __maybe_x.result.error;
goto attempt_a_fail_1;
}
unsigned char x = __maybe_x.result.value;
goto attempt_a_finally;
}
attempt_a_fail_1: {
{
attempt_a_1_a;
}
goto attempt_a_finally;
}
attempt_a_finally: {
}
}
Instead of returning __maybeErrorReturn_f->success = 0
(in the last comma expression), just return 0
. And then at the call-site, instead of:
f(&__maybe_x, 1);
if (!__maybe_x.success) {
// ..
just do:
if (!f(&__maybe_x, 1)) {
// ..
Currently
typedef enum {full} full_error;
MaybeError<void,stack_error> push(int32 x) {
return Error(full);
}
void main() {
attempt {
void p1 ?= push(1);
} fail (full_error e) {
}
}
The p1
declaration doesn't resolve to the full_error
fail block.
The desugaring of declarations does not always give the right type to variable according to the declaration.
Some examples of cdecl
:
$ cdecl
Type `help' or `?' for help
cdecl> explain int*
syntax error
cdecl> explain int* a;
declare a as pointer to int
cdecl> explain int *a[];
declare a as array of pointer to int
cdecl> explain int (*a)[];
declare a as pointer to array of int
cdecl> explain int (*a)(int);
declare a as pointer to function (int) returning int
cdecl> explain float (*a)(int);
declare a as pointer to function (int) returning float
cdecl> explain float (*a)(int *);
declare a as pointer to function (pointer to int) returning float
When compiling unsigned char *str = "hi";
with gcc -pedantic
, it complains:
test.c:8:24: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
unsigned char *str = "hi";
According to this: http://stackoverflow.com/a/4337252 char
is not the same as singed char
.
One solution is when char
is explicitly used, to not transform it into Int8()
internally, and thus as signed char
when generated to C.
Alternatively, now everywhere signed
is generated too, which is redundant for each integer type, except char, where it can be used to enforce char
objects to carry a sign. Maybe use uint8
-> unsigned char
, int8
-> signed char
, char
-> char
.
enum x {A};
MaybeError<int, enum x> f() {}
void g() {
attempt[v] {
int a ?= f();
} fail (enum x e) {
}
}
generating C for this won't work.
As designed according to the 'specification' using CSP.
When communicating between multiple processes, with multiple channels, having ONE2ONE type channels could deadlock. We don't want that.
#include <stdio.h>
#include <unistd.h>
process print(char *label, chan<char> c, chan<int> c2) {
while (1) {
char foo = c?;
printf("%s %c\n", label, foo);
c2 ! 0;
}
}
process writer(char label, int delay, chan<char> c, chan<int> c2) {
while (1) {
usleep(delay);
c ! label;
c2?;
printf("%c\n", label);
}
}
int main() {
chan<char> c;
chan<int> c2;
par {
print("P", c, c2);
writer('A', 10e4, c, c2);
writer('B', 10e4, c, c2);
writer('C', 10e4, c, c2);
}
return 0;
}
Depending on the thread that runs first (which is not deterministic), it might deadlock or not. If using ANY2ONE_CHANNEL and ONE2ANY_CHANNEL types for c
and c2
respectively, the problem is solved.
Two things need to be solved to fix this:
CSP_priAltselect
, that only accepts ONE2ONE and ANY2ONE.typedef int32 x;
void a(float32 b[], int32 c[]) {
((x) 1) + 2;
}
Gives a warning on the binary 'add' expression, while it shouldn't, as the left hand side has type x
, which is aliased to int32
, which is compatible with 2
.
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.