Ver a proveniência

Add C metaprogramming examples.

master
Ian Piumarta há 2 anos
ascendente
cometimento
eee8515a82
6 ficheiros alterados com 388 adições e 0 eliminações
  1. +3
    -0
      examples/projectExample
  2. +19
    -0
      examples/projectExample.c
  3. +149
    -0
      examples/realObjectED
  4. +34
    -0
      examples/realObjectED.c
  5. +149
    -0
      examples/realObjectPF
  6. +34
    -0
      examples/realObjectPF.c

+ 3
- 0
examples/projectExample Ver ficheiro

@ -0,0 +1,3 @@
enum foo { Closed = 0, ReadOnly = 1, WriteOnly = 2 };
static char *stateNames[] = { "Closed", "ReadOnly", "WriteOnly"};

+ 19
- 0
examples/projectExample.c Ver ficheiro

@ -0,0 +1,19 @@
@{
mapast(f, seq)
{
out = {};
for (i in seq) {
e = seq[i];
out[length(out)] = e.__proto__ != Token ? f(e) : e ;
}
out;
}
idToString(x) { { __proto__: C_string, value: "\"" + string(x.name.identifier) + "\"" } }
nil;
}
enum foo { Closed = 0, ReadOnly = 1, WriteOnly = 2 };
static char *stateNames[] = { @(mapast(idToString, program.last.enumList)) };

+ 149
- 0
examples/realObjectED Ver ficheiro

@ -0,0 +1,149 @@
// 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;
#include <math.h>
struct Point { int class; double x, y; };
oop newPoint(double x, double y)
{
struct Point *self = calloc(1, sizeof *self);
self->x = x;
self->y = y;
self->class = findClass("Point");
return (struct __oop *) self;
}
double Point_magnitude(struct __oop *__self)
{
struct Point *self = (struct Point *) __self;
printf("point method : %f\n", sqrt(self->x * self->x * self->y * self->y));
return sqrt(self->x * self->x * self->y * self->y);
}
double Point_getX(struct __oop *__self)
{
struct Point *self = (struct Point *) __self;
printf("point method : %f\n", self->x);
return self->x;
}
int main()
{
int _selector_getX= findSelector("getX");
int _selector_magnitude= findSelector("magnitude");
int _class_Point= findClass("Point");
addMethod(_class_Point, _selector_getX, (method_t) Point_getX);
addMethod(_class_Point, _selector_magnitude, (method_t) Point_magnitude);
oop p = newPoint(3, 4);
send(p, magnitude);
send(p, getX);
return 0;
}

+ 34
- 0
examples/realObjectED.c Ver ficheiro

@ -0,0 +1,34 @@
@import("parsimonyLibrary/dynamicObjectExtDecl.mc")
#include <math.h>
@class struct Point { double x, y; };
@constructor("Point") oop newPoint(double x, double y)
{
self->x = x;
self->y = y;
}
@method("Point") double magnitude()
{
printf("point method : %f\n", sqrt(self->x * self->x * self->y * self->y));
return sqrt(self->x * self->x * self->y * self->y);
}
@method("Point") double getX()
{
printf("point method : %f\n", self->x);
return self->x;
}
int main()
{
oop p = newPoint(3, 4);
@send("p", "magnitude");
@send("p", "getX");
return 0;
}

+ 149
- 0
examples/realObjectPF Ver ficheiro

@ -0,0 +1,149 @@
// 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;
#include <math.h>
struct Point { int class; double x, y; };
oop newPoint(double x, double y)
{
struct Point *self = calloc(1, sizeof *self);
self->x = x;
self->y = y;
self->class = findClass("Point");
return (struct __oop *) self;
}
double Point_magnitude(struct __oop *__self)
{
struct Point *self = (struct Point *) __self;
printf("point method : %f\n", sqrt(self->x * self->x * self->y * self->y));
return sqrt(self->x * self->x * self->y * self->y);
}
double Point_getX(struct __oop *__self)
{
struct Point *self = (struct Point *) __self;
printf("point method : %f\n", self->x);
return self->x;
}
int main()
{
int _selector_getX= findSelector("getX");
int _selector_magnitude= findSelector("magnitude");
int _class_Point= findClass("Point");
addMethod(_class_Point, _selector_getX, (method_t) Point_getX);
addMethod(_class_Point, _selector_magnitude, (method_t) Point_magnitude);
oop p = newPoint(3, 4);
// @send p magnitude();
// @send p getX();
return 0;
}

+ 34
- 0
examples/realObjectPF.c Ver ficheiro

@ -0,0 +1,34 @@
@import("parsimonyLibrary/dynamicObjectParsFrom.mc")
#include <math.h>
@class struct Point { double x, y; };
@constructor Point oop newPoint(double x, double y)
{
self->x = x;
self->y = y;
}
@method Point double magnitude()
{
printf("point method : %f\n", sqrt(self->x * self->x * self->y * self->y));
return sqrt(self->x * self->x * self->y * self->y);
}
@method Point double getX()
{
printf("point method : %f\n", self->x);
return self->x;
}
int main()
{
oop p = newPoint(3, 4);
// @send p magnitude();
// @send p getX();
return 0;
}

Carregando…
Cancelar
Guardar