Parcourir la source

Make yy context be local.

Add input struct pointer to yy context object.
Returning multiple objects from meta function appends them all to program.
Meta import via read-eval-print instead of changing input file pointer.
Add treeCopy and treeCopyUnquoting functions.
Add primitive treeCopy.
master
Ian Piumarta il y a 2 ans
Parent
révision
3a14858a70
1 fichiers modifiés avec 106 ajouts et 25 suppressions
  1. +106
    -25
      src/ccmeta.leg

+ 106
- 25
src/ccmeta.leg Voir le fichier

@ -3,7 +3,7 @@
# Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS)
# All rights reserved (see LICENSE)
#
# Last edited: 2023-03-22 17:14:46 by piumarta on zora-10.local
# Last edited: 2023-03-22 17:37:51 by piumarta on zora-10.local
%{
/* compile: leg -o ccmeta.c ccmeta.leg
@ -102,7 +102,7 @@ jb_record *jbs= NULL;
jbs= jbrec.next
// this is the global scope and other global variable for parsimony lang
oop globals= 0;
oop globals = 0;
oop program = 0;
oop prog_last = 0;
oop prog_unions = 0;
@ -151,15 +151,16 @@ void runtimeError(char *fmt, ...);
typedef struct input_t
{
oop name;
FILE *file;
struct input_t *next;
int lineNumber;
struct input_t *next;
oop name;
FILE *file;
struct _yycontext *yy;
int lineNumber;
} input_t;
input_t *inputStack= NULL;
void inputStackPush(char *name) {
void inputStackPush(struct _yycontext *yy, char *name) {
FILE *file = stdin;
if (NULL != name) {
file= fopen(name, "rb");
@ -171,21 +172,25 @@ void inputStackPush(char *name) {
name= "<stdin>";
}
input_t *input = malloc(sizeof(input_t));
input->next= inputStack;
input->name= makeString(name);
input->lineNumber= 1;
input->file= file;
input->next= inputStack;
input->yy= yy;
inputStack= input;
return;
}
input_t *inputStackPop(void) {
assert(inputStack);
fclose(inputStack->file);
input_t *first= inputStack;
inputStack= first->next;
return first;
}
void readEvalPrint(oop scope, char *fileName);
int isFalse(oop obj)
{
return obj == null || (isInteger(obj) && (0 == getInteger(obj)));
@ -887,9 +892,12 @@ oop new_C_enumerator(oop id, oop attributeSpecifier, oop expression) {
return object;
}
#define YY_INPUT(buf, result, max_size) \
#define YY_CTX_LOCAL 1 // allocate parser contexts explicitly
#define YY_CTX_MEMBERS input_t *input; // pointer back to our input structure
#define YY_INPUT(yy, buf, result, max_size) \
{ \
int yyc= feof(inputStack->file) ? EOF : getc(inputStack->file); \
int yyc= feof(yy->input->file) ? EOF : getc(yy->input->file); \
result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \
}
@ -909,7 +917,7 @@ oop eval(oop scope, oop ast);
struct _yycontext;
int yyparsefrom(int (*yystart)(struct _yycontext *yy));
int yyparsefrom(struct _yycontext *yy, int (*yystart)(struct _yycontext *yy));
int irow= 0, icol= 0;
int gnu= 1;
@ -1357,7 +1365,38 @@ oop treeCopy(oop obj)
oop map= malloc(sizeof(*obj));
memcpy(map, obj, sizeof(*obj));
for (int i = 0; i<get(obj, Map, size); i++) {
elements[i].value = treeCopy(elements[i].value);
elements[i].value = treeCopy(elements[i].value);
}
set(map, Map, elements, elements);
return map;
}
}
return obj;
}
oop treeCopyUnquoting(oop scope, oop obj)
{
switch(getType(obj)) {
case Undefined:
case Integer:
case Float:
case Function:
case Symbol:
return obj;
case String:
return makeString(get(obj, String, value));
case Map: {
struct Pair *elements= malloc(sizeof(struct Pair) * get(obj, Map, size));
memcpy(elements, get(obj, Map, elements), sizeof(struct Pair) * get(obj, Map, size));
oop map= malloc(sizeof(*obj));
memcpy(map, obj, sizeof(*obj));
for (int i = 0; i<get(obj, Map, size); i++) {
int firstCond = is(Map, elements[i].value) && map_get(elements[i].value, __proto___symbol) != null;
if (firstCond && get(map_get(map_get(elements[i].value, __proto___symbol), __name___symbol), Symbol, prototype) < t_Comment) {
elements[i].value = eval(scope, treeCopyUnquoting(scope, elements[i].value));
} else {
elements[i].value = treeCopyUnquoting(scope, elements[i].value);
}
}
set(map, Map, elements, elements);
return map;
@ -2255,7 +2294,7 @@ _FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float1
# the semicolon has to be explicit with no space eaten afterwards to prevent the
# input buffer from moving past it before redirecting input from the imported file
meta = META_IMPORT s:META_STRING ";" { $$ = null; inputStackPush(get(s, String, value)) }
meta = META_IMPORT s:META_STRING ";" { readEvalPrint(globals, get(s, String, value)); $$= 0 }
| s:meta_stmt { $$ = s }
| !. { $$ = 0 } # signal end of current input file
@ -3556,20 +3595,19 @@ void printTree(oop element, language id);
void readEvalPrint(oop scope, char *fileName)
{
inputStackPush(fileName);
struct _yycontext ctx = { 0, 0 };
inputStackPush(&ctx, fileName);
input_t *top= inputStack;
ctx.input = top;
jbRecPush();
jb_record *jtop= jbs;
int jbt= sigsetjmp(jbs->jb, 0);
if (0 == jbt) {
while (yyparse()) {
while (yyparse(&ctx)) {
if (!yylval) { // EOF
fclose(inputStack->file);
if (top == inputStack) break;
inputStackPop();
assert(inputStack);
continue;
assert(top == inputStack);
break;
}
assert(yylval);
if (null == yylval) { // change of language or input file
@ -3577,10 +3615,17 @@ void readEvalPrint(oop scope, char *fileName)
}
oop proto = map_get(yylval, __proto___symbol);
if (proto == null) {
if (is(Map, yylval)) { // multiple values returned from meta function
for (int i = 0; i < map_size(yylval); i++) {
map_append(outputProgram, treeCopyUnquoting(scope, map_get(yylval, makeInteger(i))));
}
continue;
}
println(map_keys(yylval));
printf("no prototype associated with ");
println(yylval);
fflush(stdout);
fprintf(stderr, "aborting\n");
fprintf(stderr, "(readEvalPrint - proto == null) aborting\n");
exit(1);
}
// proto_number is the enum version of the proto symbol
@ -3622,10 +3667,6 @@ oop prim_import(oop scope, oop params)
{
if (map_hasIntegerKey(params, 0)) {
char *file= get(get(params, Map, elements)[0].value, String, value);
if (yyctx->__pos < yyctx->__limit) {
yyctx->__limit--;
ungetc(yyctx->__buf[yyctx->__limit], inputStack->file);
}
readEvalPrint(scope, file);
}
return null;
@ -3642,6 +3683,46 @@ oop prim_scope(oop scope, oop params)
return fixScope(scope);
}
oop prim_parseFrom(oop scope, oop params)
{
if (map_size(params) != 1) return null;
oop name = get(params, Map, elements)[0].value;
if (!is(String, name)) return null;
char *s = get(name, String, value);
assert(inputStack);
struct _yycontext *zz = inputStack->yy;
struct _yycontext ctx, *yy = &ctx;
memcpy(&ctx, zz, sizeof(struct _yycontext));
yy->__thunkslen= YY_STACK_SIZE;
yy->__thunks= (yythunk *)YY_MALLOC(yy, sizeof(yythunk) * yy->__thunkslen);
yy->__valslen= YY_STACK_SIZE;
yy->__vals= (YYSTYPE *)YY_MALLOC(yy, sizeof(YYSTYPE) * yy->__valslen);
yy->__thunkpos= 0;
int res;
if (!strcmp(s, "declaration" )) res = yyparsefrom(yy, yy_declaration );
else if (!strcmp(s, "expression" )) res = yyparsefrom(yy, yy_expression );
else if (!strcmp(s, "statement" )) res = yyparsefrom(yy, yy_statement );
else if (!strcmp(s, "id" )) res = yyparsefrom(yy, yy_id );
else if (!strcmp(s, "func" )) res = yyparsefrom(yy, yy_functionDefinition);
else if (!strcmp(s, "error" )) res = yyparsefrom(yy, yy_error );
else {
fprintf(stderr, "parseFrom: %s not implemented", s);
exit(1);
}
oop value;
if (res) {
value = __;
zz->__buf= yy->__buf;
zz->__buflen= yy->__buflen;
zz->__pos= yy->__pos;
zz->__limit= yy->__limit;
} else {
printf("%s expected\n", s);
value = null;
}
return value;
}
#include <sys/resource.h>
oop prim_microseconds(oop scope, oop params)

Chargement…
Annuler
Enregistrer