// 1. put a real object system inside the tree-based parsing stuff
|
|
// 2. implement ? operator (zero or one of something)
|
|
// 3. implement . leaf type (any valid character, NOT the end of the input)
|
|
// 4. implement ! operator (prefix, inverts the subexpression) !"abc" matches not "abc" without moving input
|
|
// 5. make a function to print the tree describing the pattern
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
typedef union Object Object;
|
|
typedef union Object *oop;
|
|
|
|
enum type {
|
|
Integer,
|
|
String,
|
|
};
|
|
|
|
struct Integer { enum type type; int i; };
|
|
struct String { enum type type; char *s; int len; };
|
|
|
|
union Object {
|
|
enum type type;
|
|
struct Integer Integer;
|
|
struct String String;
|
|
};
|
|
|
|
oop mkObject(size_t size, enum type type)
|
|
{
|
|
oop o= calloc(1, size);
|
|
o->type = type;
|
|
return o;
|
|
}
|
|
|
|
oop _checktype(oop object, enum type type)
|
|
{
|
|
if (object->type == type) return object;
|
|
fprintf(stderr, "\naccesing type %i as if it were a %i\n", object->type, type);
|
|
exit(1);
|
|
return 0;
|
|
}
|
|
|
|
#define new(type) mkObject(sizeof(struct type), type)
|
|
|
|
#define get(object, type, member) (_checktype(object, type)->type.member)
|
|
|
|
|
|
oop mkInt(int i)
|
|
{
|
|
oop o= new(Integer);
|
|
o->Integer.i = i;
|
|
return o;
|
|
}
|
|
|
|
oop mkStr(char *s)
|
|
{
|
|
oop o= new(String);
|
|
o->String.s = s;
|
|
o->String.len = strlen(s);
|
|
return o;
|
|
}
|
|
|
|
void println(oop o)
|
|
{
|
|
switch (o->type) {
|
|
case Integer: printf("%i\n", get(o, Integer, i)); return;
|
|
case String: printf("%.*s\n", get(o, String, len), get(o, String, s)); return;
|
|
}
|
|
abort();
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
println(mkInt(42));
|
|
println(mkStr("hello world"));
|
|
|
|
return 0;
|
|
}
|
|
|