Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2006-2008 The PARI group.12This file is part of the PARI package.34PARI/GP is free software; you can redistribute it and/or modify it under the5terms of the GNU General Public License as published by the Free Software6Foundation; either version 2 of the License, or (at your option) any later7version. It is distributed in the hope that it will be useful, but WITHOUT8ANY WARRANTY WHATSOEVER.910Check the License for details. You should have received a copy of it, along11with the package; see the file 'COPYING'. If not, write to the Free Software12Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */1314#include "pari.h"15#include "paripriv.h"16BEGINEXTERN17#include "parse.h"18ENDEXTERN19#include "anal.h"20#include "tree.h"2122static THREAD int pari_once;23static THREAD long pari_discarded;24static THREAD const char *pari_lex_start;25static THREAD GEN pari_lasterror;2627static void pari_error(PARI_LTYPE *yylloc, char **lex, const char *s)28{29(void) yylloc; (void) lex;30if (pari_lasterror) cgiv(pari_lasterror);31pari_lasterror=strtoGENstr(s);32}3334static THREAD pari_stack s_node;35THREAD node *pari_tree;3637void38pari_init_parser(void)39{40long i;41const char *opname[]={"_||_", "_&&_", "_===_", "_==_", "_!=_", "_>=_", "_>_", "_<=_", "_<_", "_-_","_+_","_<<_", "_>>_", "_%_", "_\\/_", "_\\_", "_/_", "_*_","_^_","__","_--","_++","_-=_", "_+=_", "_<<=_", "_>>=_", "_%=_", "_\\/=_", "_\\=_", "_/=_", "_*=_","+_","-_","!_","_!","_'_","_~","[_.._]","[_|_<-_,_]","[_|_<-_,_;_]","%","%#","#_",""};4243pari_stack_init(&s_node,sizeof(*pari_tree),(void **)&pari_tree);44pari_stack_alloc(&s_node,OPnboperator);45parsestate_reset();46for (i=0;i<OPnboperator;i++)47{48pari_tree[i].f = Fconst;49pari_tree[i].x = CSTentry;50pari_tree[i].y = -1;51pari_tree[i].str = opname[i];52pari_tree[i].len = strlen(opname[i]);53pari_tree[i].flags= 0;54}55}56void57pari_close_parser(void) { pari_stack_delete(&s_node); }5859void60compile_err(const char *msg, const char *str)61{62pari_err(e_SYNTAX, msg, str, pari_lex_start);63}6465void66compile_varerr(const char *str)67{68pari_err(e_SYNTAX, "variable name expected", str, pari_lex_start);69}7071void72parsestate_reset(void)73{74s_node.n = OPnboperator;75pari_lex_start = NULL;76pari_once=1;77pari_discarded=0;78pari_lasterror=NULL;79}80void81parsestate_save(struct pari_parsestate *state)82{83state->node = s_node.n;84state->lex_start = pari_lex_start;85state->once = pari_once;86state->discarded = pari_discarded;87state->lasterror = pari_lasterror;88}89void90parsestate_restore(struct pari_parsestate *state)91{92s_node.n = state->node;93pari_lex_start = state->lex_start;94pari_once = state->once;95pari_discarded = state->discarded;96pari_lasterror = state->lasterror;97}9899GEN100pari_compile_str(const char *lex)101{102pari_sp ltop=avma;103GEN code;104struct pari_parsestate state;105parsestate_save(&state);106pari_lex_start = lex;107pari_once=1;108pari_discarded=0;109pari_lasterror=NULL;110if (pari_parse((char**)&lex) || pari_discarded)111{112if (pari_lasterror)113compile_err(GSTR(pari_lasterror),lex-1);114else /* should not happen */115compile_err("syntax error",lex-1);116}117set_avma(ltop);118optimizenode(s_node.n-1);119code=gp_closure(s_node.n-1);120parsestate_restore(&state);121return code;122}123124static long125newnode(Ffunc f, long x, long y, struct node_loc *loc)126{127long n=pari_stack_new(&s_node);128pari_tree[n].f=f;129pari_tree[n].x=x;130pari_tree[n].y=y;131pari_tree[n].str=loc->start;132pari_tree[n].len=loc->end-loc->start;133pari_tree[n].flags=0;134return n;135}136137static long138newconst(long x, struct node_loc *loc)139{140return newnode(Fconst,x,-1,loc);141}142143static long144newopcall(OPerator op, long x, long y, struct node_loc *loc)145{146if (y==-1)147return newnode(Ffunction,op,x,loc);148else149return newnode(Ffunction,op,newnode(Flistarg,x,y,loc),loc);150}151152static long153newopcall3(OPerator op, long x, long y, long z, struct node_loc *loc)154{155return newopcall(op,newnode(Flistarg,x,y,loc),z,loc);156}157158static long159countarg(long n)160{161long i;162for(i=1; pari_tree[n].f==Flistarg; i++)163n = pari_tree[n].x;164return i;165}166167static long168addcurrexpr(long n, long currexpr, struct node_loc *loc)169{170long y, m = n;171while (pari_tree[m].x==OPcomprc)172{173y = pari_tree[m].y; if (countarg(y)==4) y = pari_tree[y].x;174m = pari_tree[y].y;175}176y = pari_tree[m].y; if (countarg(y)==4) y = pari_tree[y].x;177pari_tree[y].y = currexpr;178pari_tree[n].str=loc->start;179pari_tree[n].len=loc->end-loc->start;180return n;181}182183static long184newintnode(struct node_loc *loc)185{186if (loc->end-loc->start<=(long)(1+LOG10_2*BITS_IN_LONG))187{188pari_sp ltop=avma;189GEN g=strtoi(loc->start);190long s = itos_or_0(g), sg = signe(g);191set_avma(ltop);192if (sg==0 || s) return newnode(Fsmall,s,-1,loc);193}194return newconst(CSTint,loc);195}196197static long198newfunc(CSTtype t, struct node_loc *func, long args, long code,199struct node_loc *loc)200{201long name=newnode(Fentry,newconst(t,func),-1,func);202return newnode(Fassign,name,newnode(Flambda,args,code,loc),loc);203}204205206207208