Przeglądaj źródła

Add boot and library meta code.

master
Ian Piumarta 2 lat temu
rodzic
commit
c4d102b983
4 zmienionych plików z 767 dodań i 0 usunięć
  1. +179
    -0
      src/parsimonyLibrary/boot.mc
  2. +134
    -0
      src/parsimonyLibrary/dynamicObject.c
  3. +233
    -0
      src/parsimonyLibrary/dynamicObjectExtDecl.mc
  4. +221
    -0
      src/parsimonyLibrary/dynamicObjectParsFrom.mc

+ 179
- 0
src/parsimonyLibrary/boot.mc Wyświetl plik

@ -0,0 +1,179 @@
@{
// create the function println
println(){
apply(print, __arguments__);
print("\n");
__arguments__;
}
__requires__ = {};
// Import the file
require(__fileName__)
{
if (__requires__[__fileName__] != null)
{
return __requires__[__fileName__]
}
import(__fileName__);
__requires__[__fileName__] = scope();
return scope();
}
// Get the current time in milliseconds
millis()
{
microseconds() / 1000;
}
// Get the last element of s
last(s)
{
s[length(s) - 1];
}
// adding the element e at the end of the list l
append(s, e)
{
s[length(s)] = e;
}
// adding the element e at the end of the list l
push(s, e)
{
append(s, e);
}
// remove the last element of the list s or remove the element e if not null
pop(s, e)
{
if (e == null)
{
e = length(s) - 1
}
ret = s[e];
t = {};
for (i in s)
{
if (i == e)
continue;
append(t, s[i]);
}
s = t;
ret;
}
// add or don't change an element in a dictionnary
intern(s, e)
{
lo = 0;
hi = length(s) - 1;
while (lo <= hi)
{
mid = (lo + hi) / 2;
if (e > s[mid])
lo = mid + 1;
else if (e < s[mid])
hi = mid - 1;
else
return e;
}
for (i = length(s); i > lo; i = i - 1)
{
s[i] = s[i - 1];
}
return s[lo] = e;
}
// merge the two list s1 and s2
fusion(s1, s2)
{
for (i in s2)
{
append(s1, s2[i]);
}
return s1;
}
// If g then we add a filter on the application of the function f to each element of seq
map(f, seq, g)
{
out = {};
if (!g) g = (){ 1 };
for (i in seq) {
e = seq[i];
out[length(out)] = g(e) ? f(e) : e ;
}
out;
}
notToken(x){x.__proto__ != Token}
// Select element e of s if the the result of the application of f on e is true
select(f, s)
{
out = {};
for (i in s)
{
e = s[i];
if (f(e))
{
append(out, e);
}
}
out;
}
// Select element e of s if the the result of the application of f on e is false
reject(f, s)
{
out = {};
for (i in s)
{
e = s[i];
if (!f(e))
{
append(out, e);
}
}
out;
}
//------------ C structure ------------//
newId(x, comm)
{
if (comm == null)
{
{identifier : x, __proto__ : C_id};
}
else
{
{identifier : x, comment : {text : comm, __proto__ : Comment}, __proto__ : C_id};
}
}
newText(x) { {value : x, __proto__ : C_string}; }
newComment(com) { {text : com, __proto__ : Comment}; }
newToken(txt, com)
{
if (com == null) return {text : txt, comment : newComment(""), __proto__ : Token};
{text : txt, comment : newComment(com), __proto__ : Token};
}
newSemicolon(com){newToken(";", com)}
newComma() { newToken(",", " "); }
newStar(com) { newToken("*", com); }
newBinary(com) { newToken("=", com); }
newEnum(x) { {attributeL : null, expression : null, name : newId(x), __proto__ : C_enum}; }
//-------------------- end ---------------------//
nil;
}

+ 134
- 0
src/parsimonyLibrary/dynamicObject.c Wyświetl plik

@ -0,0 +1,134 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Symbol {
char *name;
int class, selector;
};
struct Symbol *newSymbol(char *name)
{
struct Symbol *symbol = malloc(sizeof(*symbol));
symbol->name = strdup(name);
symbol->class = 0;
symbol->selector = 0;
return symbol;
}
struct Symbol **symbols = 0;
int nSymbols = 0;
struct Symbol *intern(char *name)
{
int lo = 0;
int hi = nSymbols - 1;
while (lo <= hi ) {
int mid = (lo+hi)/2;
int cmp = strcmp(name, symbols[mid]->name);
if (cmp > 0) lo = mid + 1;
else if (cmp < 0) hi = mid - 1;
else return symbols[mid];
}
symbols = realloc(symbols, sizeof(*symbols) * ++nSymbols);
memmove(symbols + lo + 1, symbols + lo, sizeof(*symbols)*(nSymbols - lo - 1));
return symbols[lo] = newSymbol(name);
}
typedef void *(*method_t)();
void *method_dnu()
{
printf("method not found\n");
exit(1);
return 0;
}
method_t **methods = 0;
int nClasses = 0;
int nSelectors = 0;
int ensureClass(struct Symbol *symbol)
{
if (symbol->class == 0) {
if (nClasses == 0) nClasses++;
symbol->class = nClasses++;
methods = realloc(methods, sizeof(*methods)*nClasses);
methods[symbol->class] = malloc(sizeof(*methods)*nSelectors);
for (int i = 0; i<nSelectors; ++i)
methods[symbol->class][i] = method_dnu;
}
return symbol->class;
}
int ensureSelector(struct Symbol *symbol)
{
if (symbol->selector == 0) {
if (nSelectors == 0) nSelectors++;
symbol->selector = nSelectors++;
for (int i = 0; i<nClasses; ++i) {
methods[i] = realloc(methods[i], sizeof(**methods)*nSelectors);
methods[i][nSelectors-1] = method_dnu;
}
}
return symbol->selector;
}
int findClass(char *class)
{
return ensureClass(intern(class));
}
int findSelector(char *selector)
{
return ensureSelector(intern(selector));
}
void addMethod(int class, int selector, method_t method)
{
methods[class][selector] = method;
}
#define lookup(C, S) (methods[C][S])
struct Object {
int class;
};
void *Object_print()
{
printf("Object\n");
return 0;
}
struct Point {
int class;
double x, y;
};
void *Point_print(struct Point *self)
{
printf("Point(%f, %f)\n", self->x, self->y);
return 0;
}
#define send(R, M, ...) ({ struct Object *__ = (struct Object *)(R); lookup(__->class, _selector_##M)(__, ##__VA_ARGS__); })
int main()
{
int _selector_print = findSelector("print" );
int _class_object = findClass ("Object" );
int _class_point = findClass ("Point" );
addMethod(_class_object, _selector_print, Object_print);
struct Object *o = calloc(1, sizeof(*o));
o->class = _class_object;
send(o, print);
addMethod(_class_point, _selector_print, Point_print);
struct Point *p = calloc(1, sizeof(*p));
p->class = _class_point;
send(p, print);
return 0;
}

+ 233
- 0
src/parsimonyLibrary/dynamicObjectExtDecl.mc Wyświetl plik

@ -0,0 +1,233 @@
// This example serves to illustrate the possibility
// of adding the object aspect to C
// using the everyExternalDeclaration function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Symbol {
char *name;
int class, selector;
};
struct Symbol *newSymbol(char *name)
{
struct Symbol *symbol = malloc(sizeof(*symbol));
symbol->name = strdup(name);
symbol->class = 0;
symbol->selector = 0;
return symbol;
}
struct Symbol **symbols = 0;
int nSymbols = 0;
struct Symbol *intern(char *name)
{
int lo = 0;
int hi = nSymbols - 1;
while (lo <= hi ) {
int mid = (lo+hi)/2;
int cmp = strcmp(name, symbols[mid]->name);
if (cmp > 0) lo = mid + 1;
else if (cmp < 0) hi = mid - 1;
else return symbols[mid];
}
symbols = realloc(symbols, sizeof(*symbols) * ++nSymbols);
memmove(symbols + lo + 1, symbols + lo, sizeof(*symbols)*(nSymbols - lo - 1));
return symbols[lo] = newSymbol(name);
}
typedef void *(*method_t)();
void *method_dnu()
{
printf("method not found\n");
exit(1);
return 0;
}
method_t **methods = 0;
int nClasses = 0;
int nSelectors = 0;
int ensureClass(struct Symbol *symbol)
{
if (symbol->class == 0) {
if (nClasses == 0) nClasses++;
symbol->class = nClasses++;
methods = realloc(methods, sizeof(*methods)*nClasses);
methods[symbol->class] = malloc(sizeof(*methods)*nSelectors);
for (int i = 0; i<nSelectors; ++i)
methods[symbol->class][i] = method_dnu;
}
return symbol->class;
}
int ensureSelector(struct Symbol *symbol)
{
if (symbol->selector == 0) {
if (nSelectors == 0) nSelectors++;
symbol->selector = nSelectors++;
for (int i = 0; i<nClasses; ++i) {
methods[i] = realloc(methods[i], sizeof(**methods)*nSelectors);
methods[i][nSelectors-1] = method_dnu;
}
}
return symbol->selector;
}
int findClass(char *class)
{
return ensureClass(intern(class));
}
int findSelector(char *selector)
{
return ensureSelector(intern(selector));
}
void addMethod(int class, int selector, method_t method)
{
methods[class][selector] = method;
}
#define lookup(C, S) (methods[C][S])
struct Object {
int class;
};
#define send(R, M, ...) ({ struct Object *__ = (struct Object *)(R); lookup(__->class, _selector_##M)(__, ##__VA_ARGS__); })
struct __oop { int class; };
typedef struct __oop *oop;
@import("../src/parsimonyLibrary/boot.mc")
@{
rmSemi(x) {
x.semicolon = null;
x;
}
makeln(x, tabs, newLine) {
x.semicolon.comment = newComment("\n");
nbTabs = 0;
nbLn = 1;
if (tabs != null) { nbTabs = tabs; }
if (newLine != null) { nbLn = newLine; }
for (i = 1; i<nbLn; i++) {
x.semicolon.comment.text = x.semicolon.comment.text + "\n";
}
for (i = 0; i<tabs; i++) {
x.semicolon.comment.text = x.semicolon.comment.text + " ";
}
x;
}
program.objects = {};
program.objects.class = {};
program.objects.methods = {};
class()
{
program.objects.function = "class";
nil;
}
method(object_name)
{
program.objects.currentClassName = object_name;
program.objects.function = "method";
nil;
}
constructor(object_name) {
program.objects.currentClassName = object_name;
program.objects.function = "constructor";
nil;
}
send(object, method)
{
rmSemi(`declaration send(@@(newText(object)), @@(newText(method))););
}
everyExternalDeclaration(s)
{
/*********** Class function ************/
if (program.objects.function == "class") {
program.objects.class[program.last.name.identifier] = {};
for (i=length(program.last.declarationL); i>0; i--) {
program.last.declarationL[i] = program.last.declarationL[i-1];
};
program.last.declarationL[0] = `declaration int class; ;
program.objects.function = "none";
return s;
}
/*********** Method function ************/
if (program.objects.function == "method") {
intern(program.objects.methods, program.last.declarators.declarators.identifier);
for (i in program.objects.class) {
if (string(i) == program.objects.currentClassName) intern(program.objects.class[i], program.last.declarators.declarators.identifier);
}
program.last.declarators.declarators.identifier = program.objects.currentClassName + "_" + string(program.last.declarators.declarators.identifier);
param = rmSemi(`declaration struct __oop *__self;);
if (length(s.declarators.paramTypeL) > 0) {
append(s.declarators.paramTypeL, newComma());
append(s.declarators.paramTypeL, param);
} else {
s.declarators.paramTypeL = {};
s.declarators.paramTypeL[0] = param;
}
tmp = {};
tmp[0] = makeln(`declaration struct @@(newId(program.objects.currentClassName, " ")) *self = (struct @@(newId(program.objects.currentClassName, " ")) *) __self;, 1);
s.compoundS.expression = fusion(tmp, s.compoundS.expression);
program.objects.function = "none";
return s;
}
/*********** Constructor function ************/
if (program.objects.function == "constructor") {
rawDeclaration = makeln(`declaration class = findClass(@@(newText("\"" + program.objects.currentClassName + "\"")));, 1);
t = {};
append(t, makeln(`declaration struct @@(newId(program.objects.currentClassName, " ")) *self = calloc(1, sizeof *self);, 1));
// take the structure of self->foo
lhs = treeCopy(s.compoundS.expression[0].expression.lhs);
lhs.rhs = newId("class", " ");
// Change foo to Class
rawDeclaration.declarators[0].lhs = lhs;
// prepare the right object to return
append(s.compoundS.expression, rawDeclaration);
append(s.compoundS.expression, makeln(`statement return (struct __oop *) self;));
s.compoundS.expression = fusion(t, s.compoundS.expression);
program.objects.function = "none";
return s;
}
/*********** Main function ************/
if (s.declarators != null && s.declarators.declarators != null && string(s.declarators.declarators.identifier) == "main") {
t = {};
for(i in program.objects.methods) {
methodName = string(program.objects.methods[i]);
append(t, makeln(`declaration int @@(newId("_selector_" + methodName)) = findSelector(@@(newId("\"" + methodName + "\"")));, 1));
}
for (i in program.objects.class) {
className = string(i);
append(t, makeln(`declaration int @@(newId("_class_" + className)) = findClass(@@(newId("\"" + className + "\"")));, 1));
for (k in program.objects.class[i]) {
linkedMethod = string(program.objects.class[i][k]);
castMethod = "(method_t) " + className + "_" + linkedMethod;
append(t, makeln(`declaration addMethod(@@(newId("_class_" + className)), @@(newId("_selector_" + linkedMethod)), @@(newId(castMethod)));, 1));
}
}
s.compoundS.expression = fusion(t, s.compoundS.expression);
return s;
}
s;
}
nil;
}

+ 221
- 0
src/parsimonyLibrary/dynamicObjectParsFrom.mc Wyświetl plik

@ -0,0 +1,221 @@
// This example serves to illustrate the possibility
// of adding the object aspect to C
// using the parseFrom primitive.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Symbol {
char *name;
int class, selector;
};
struct Symbol *newSymbol(char *name)
{
struct Symbol *symbol = malloc(sizeof(*symbol));
symbol->name = strdup(name);
symbol->class = 0;
symbol->selector = 0;
return symbol;
}
struct Symbol **symbols = 0;
int nSymbols = 0;
struct Symbol *intern(char *name)
{
int lo = 0;
int hi = nSymbols - 1;
while (lo <= hi ) {
int mid = (lo+hi)/2;
int cmp = strcmp(name, symbols[mid]->name);
if (cmp > 0) lo = mid + 1;
else if (cmp < 0) hi = mid - 1;
else return symbols[mid];
}
symbols = realloc(symbols, sizeof(*symbols) * ++nSymbols);
memmove(symbols + lo + 1, symbols + lo, sizeof(*symbols)*(nSymbols - lo - 1));
return symbols[lo] = newSymbol(name);
}
typedef void *(*method_t)();
void *method_dnu()
{
printf("method not found\n");
exit(1);
return 0;
}
method_t **methods = 0;
int nClasses = 0;
int nSelectors = 0;
int ensureClass(struct Symbol *symbol)
{
if (symbol->class == 0) {
if (nClasses == 0) nClasses++;
symbol->class = nClasses++;
methods = realloc(methods, sizeof(*methods)*nClasses);
methods[symbol->class] = malloc(sizeof(*methods)*nSelectors);
for (int i = 0; i<nSelectors; ++i)
methods[symbol->class][i] = method_dnu;
}
return symbol->class;
}
int ensureSelector(struct Symbol *symbol)
{
if (symbol->selector == 0) {
if (nSelectors == 0) nSelectors++;
symbol->selector = nSelectors++;
for (int i = 0; i<nClasses; ++i) {
methods[i] = realloc(methods[i], sizeof(**methods)*nSelectors);
methods[i][nSelectors-1] = method_dnu;
}
}
return symbol->selector;
}
int findClass(char *class)
{
return ensureClass(intern(class));
}
int findSelector(char *selector)
{
return ensureSelector(intern(selector));
}
void addMethod(int class, int selector, method_t method)
{
methods[class][selector] = method;
}
#define lookup(C, S) (methods[C][S])
struct Object {
int class;
};
#define send(R, M, ...) ({ struct Object *__ = (struct Object *)(R); lookup(__->class, _selector_##M)(__, ##__VA_ARGS__); })
struct __oop { int class; };
typedef struct __oop *oop;
@import("../src/parsimonyLibrary/boot.mc")
@{
rmSemi(x) {
x.semicolon = null;
x;
}
makeln(x, tabs, newLine) {
x.semicolon.comment = newComment("\n");
nbTabs = 0;
nbLn = 1;
if (tabs != null) { nbTabs = tabs; }
if (newLine != null) { nbLn = newLine; }
for (i = 1; i<nbLn; i++) {
x.semicolon.comment.text = x.semicolon.comment.text + "\n";
}
for (i = 0; i<tabs; i++) {
x.semicolon.comment.text = x.semicolon.comment.text + " ";
}
x;
}
program.objects = {};
program.objects.class = {};
program.objects.methods = {};
class()
{
exp = parseFrom("declaration");
program.objects.class[exp.specifiers[0].name.identifier] = {};
for (i=length(exp.specifiers[0].declarationL); i>0; i--) {
exp.specifiers[0].declarationL[i] = exp.specifiers[0].declarationL[i-1];
};
exp.specifiers[0].declarationL[0] = `declaration int class; ;
exp;
}
method()
{
id = string(parseFrom("id").identifier);
decl = parseFrom("func");
intern(program.objects.methods, decl.declarators.declarators.identifier);
for (i in program.objects.class) {
if (string(i) == id) intern(program.objects.class[i], decl.declarators.declarators.identifier);
}
decl.declarators.declarators.identifier = id + "_" + string(decl.declarators.declarators.identifier);
param = rmSemi(`declaration struct __oop *__self;);
if (length(decl.declarators.paramTypeL) > 0) {
append(decl.declarators.paramTypeL, newComma());
append(decl.declarators.paramTypeL, param);
} else {
decl.declarators.paramTypeL = {};
decl.declarators.paramTypeL[0] = param;
}
tmp = {};
tmp[0] = makeln(`declaration struct @@(newId(id, " ")) *self = (struct @@(newId(id, " ")) *) __self;, 1);
decl.compoundS.expression = fusion(tmp, decl.compoundS.expression);
program.objects.function = "none";
decl;
}
constructor() {
id = string(parseFrom("id").identifier);
decl = parseFrom("func");
rawDeclaration = makeln(`declaration class = findClass(@@(newText("\"" + id + "\"")));, 1);
t = {};
append(t, makeln(`declaration struct @@(newId(id, " ")) *self = calloc(1, sizeof *self);, 1));
// take the structure of self->foo
lhs = treeCopy(decl.compoundS.expression[0].expression.lhs);
lhs.rhs = newId("class", " ");
// Change foo to Class
rawDeclaration.declarators[0].lhs = lhs;
// prepare the right object to return
append(decl.compoundS.expression, rawDeclaration);
append(decl.compoundS.expression, makeln(`statement return (struct __oop *) self;));
decl.compoundS.expression = fusion(t, decl.compoundS.expression);
program.objects.function = "none";
decl;
}
// TODO
send()
{
nil;
}
everyExternalDeclaration(s)
{
/*********** Main function ************/
if (s.declarators != null && s.declarators.declarators != null && string(s.declarators.declarators.identifier) == "main") {
t = {};
for(i in program.objects.methods) {
methodName = string(program.objects.methods[i]);
append(t, makeln(`declaration int @@(newId("_selector_" + methodName)) = findSelector(@@(newId("\"" + methodName + "\"")));, 1));
}
for (i in program.objects.class) {
className = string(i);
append(t, makeln(`declaration int @@(newId("_class_" + className)) = findClass(@@(newId("\"" + className + "\"")));, 1));
for (k in program.objects.class[i]) {
linkedMethod = string(program.objects.class[i][k]);
castMethod = "(method_t) " + className + "_" + linkedMethod;
append(t, makeln(`declaration addMethod(@@(newId("_class_" + className)), @@(newId("_selector_" + linkedMethod)), @@(newId(castMethod)));, 1));
}
}
s.compoundS.expression = fusion(t, s.compoundS.expression);
return s;
}
s;
}
nil;
}

Ładowanie…
Anuluj
Zapisz