瀏覽代碼

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 2 年之前
父節點
當前提交
3a14858a70
共有 1 個文件被更改,包括 106 次插入25 次删除
  1. +106
    -25
      src/ccmeta.leg

+ 106
- 25
src/ccmeta.leg 查看文件

@ -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)

Loading…
取消
儲存