fix: release loaded program storage

This commit is contained in:
Hermes Agent
2026-09-23 04:58:43 +00:00
parent d05465b299
commit 56b72d8ba5
3 changed files with 10 additions and 4 deletions
+3 -1
View File
@@ -285,6 +285,8 @@ static void value_list_reverse(Value v){ int i; if(v.type!=V_LIST||!v.list) retu
/* ---------- program loading / blocks ---------- */
static Program *load_program(Runtime *rt,const char *path){ FILE *f; char buf[4096]; Program *p; int i; for(i=0;i<rt->pcount;i++) if(strcmp(rt->programs[i]->path,path)==0) return rt->programs[i]; f=fopen(path,"rb"); if(!f) return NULL; p=(Program*)xmalloc(sizeof(Program)); p->path=xstrdup(path); p->lines=NULL; p->count=p->cap=0; while(fgets(buf,sizeof(buf),f)){ size_t n=strlen(buf); while(n&& (buf[n-1]=='\n'||buf[n-1]=='\r')) buf[--n]=0; if(p->count>=p->cap){ p->cap=p->cap?p->cap*2:32; p->lines=(char**)xrealloc(p->lines,sizeof(char*)*p->cap);} p->lines[p->count++]=xstrdup(buf); } fclose(f); if(rt->pcount>=rt->pcap){ rt->pcap=rt->pcap?rt->pcap*2:16; rt->programs=(Program**)xrealloc(rt->programs,sizeof(Program*)*rt->pcap);} rt->programs[rt->pcount++]=p; return p; }
static void program_free(Program *p){ int i; if(!p) return; for(i=0;i<p->count;i++) free(p->lines[i]); free(p->lines); free(p->path); free(p); }
static void runtime_programs_free(Runtime *rt){ int i; if(!rt) return; for(i=0;i<rt->pcount;i++) program_free(rt->programs[i]); free(rt->programs); rt->programs=NULL; rt->pcount=rt->pcap=0; }
static void scan_functions(Runtime *rt,Program *p,const char *prefix);
static void line_word(Program *p,int i,char *up,size_t n){ char tmp[512],w[128]; strncpy(tmp,p->lines[i],sizeof(tmp)-1); tmp[sizeof(tmp)-1]=0; first_word(trim_inplace(tmp),w,sizeof(w)); upper_copy(up,w,n); }
static int line_is_block_opener(Program *p,int i,const char *up){ char *t; char tmp[512]; if(ci_eq(up,"IF")||ci_eq(up,"FOR")||ci_eq(up,"REPEAT")||ci_eq(up,"TEACH")||ci_eq(up,"TRY")||ci_eq(up,"COMMENT")||ci_eq(up,"CLASS")) return 1; if(ci_eq(up,"DO")){ strncpy(tmp,p->lines[i],sizeof(tmp)-1); tmp[sizeof(tmp)-1]=0; t=trim_inplace(tmp); return find_word_ci(t,"TIMES")!=NULL; } if(ci_eq(up,"START")){ strncpy(tmp,p->lines[i],sizeof(tmp)-1); tmp[sizeof(tmp)-1]=0; t=trim_inplace(tmp); return starts_ci(t+5," TASK"); } return 0; }
@@ -462,7 +464,7 @@ static void exec_line(Runtime *rt,Program *p,int *pcp,const char *raw){ char buf
if(strcmp(up,"CREATE")==0||strcmp(up,"MOVE")==0||strcmp(up,"SHOW")==0||strcmp(up,"HIDE")==0||strcmp(up,"EXPORT")==0||strcmp(up,"LEARNED")==0||strcmp(up,"ENDIF")==0||strcmp(up,"ELSE")==0||strcmp(up,"DONE")==0||strcmp(up,"ENDTRY")==0||strcmp(up,"CATCH")==0||strcmp(up,"ENDCOMMENT")==0||strcmp(up,"END")==0||strcmp(up,"WAIT")==0){ return; }
rt_error(rt,p->path,pc+1,"Unknown command: %s",w); }
static void exec_range(Runtime *rt,Program *p,int start,int end){ int pc; if(end<0||end>p->count) end=p->count; for(pc=start; pc<end && !rt->error && !rt->returning; pc++) exec_line(rt,p,&pc,p->lines[pc]); }
static int run_file(Runtime *rt,const char *path){ Program *p=load_program(rt,path); if(!p){ fprintf(stderr,"Could not open %s: %s\n",path,strerror(errno)); return 1;} scan_functions(rt,p,""); exec_range(rt,p,0,p->count); if(rt->error){ if(!rt->capture) fprintf(stderr,"%s:%d: %s\n",rt->err_file?rt->err_file:path,rt->err_line,rt->err_msg?rt->err_msg:"error"); return 1;} return 0; }
static int run_file(Runtime *rt,const char *path){ Program *p=load_program(rt,path); int rc; if(!p){ fprintf(stderr,"Could not open %s: %s\n",path,strerror(errno)); return 1;} scan_functions(rt,p,""); exec_range(rt,p,0,p->count); rc=rt->error?1:0; if(rt->error&&!rt->capture) fprintf(stderr,"%s:%d: %s\n",rt->err_file?rt->err_file:path,rt->err_line,rt->err_msg?rt->err_msg:"error"); runtime_programs_free(rt); return rc; }
/* ---------- formatter/check/test runner ---------- */
static int fmt_file(const char *path){ FILE *f=fopen(path,"rb"); char line[4096]; int indent=0; if(!f){ fprintf(stderr,"Could not open %s\n",path); return 1;} while(fgets(line,sizeof(line),f)){ char *t=trim_inplace(line),w[64],up[64]; int opens=0; first_word(t,w,sizeof(w)); upper_copy(up,w,sizeof(up)); if(!strcmp(up,"ENDIF")||!strcmp(up,"LEARNED")||!strcmp(up,"DONE")||!strcmp(up,"ENDTRY")||!strcmp(up,"ELSE")||!strcmp(up,"CATCH")||!strcmp(up,"ENDCOMMENT")||!strcmp(up,"ENDCLASS")||!strcmp(up,"ENDTASK")||!strcmp(up,"END")) indent-=4; if(indent<0) indent=0; for(int i=0;i<indent;i++) putchar(' '); puts(t); opens=!strcmp(up,"TEACH")||!strcmp(up,"IF")||!strcmp(up,"FOR")||!strcmp(up,"TRY")||!strcmp(up,"CLASS")||!strcmp(up,"START")||!strcmp(up,"COMMENT")||!strcmp(up,"REPEAT")||!strcmp(up,"ELSE")||!strcmp(up,"CATCH")||(!strcmp(up,"DO")&&find_word_ci(t,"TIMES")); if(opens) indent+=4; } fclose(f); return 0; }