Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Testing latest pari + WASM + node.js... and it works?! Wow.

28495 views
License: GPL3
ubuntu2004
1
/* Copyright (C) 2006-2008 The PARI group.
2
3
This file is part of the PARI package.
4
5
PARI/GP is free software; you can redistribute it and/or modify it under the
6
terms of the GNU General Public License as published by the Free Software
7
Foundation; either version 2 of the License, or (at your option) any later
8
version. It is distributed in the hope that it will be useful, but WITHOUT
9
ANY WARRANTY WHATSOEVER.
10
11
Check the License for details. You should have received a copy of it, along
12
with the package; see the file 'COPYING'. If not, write to the Free Software
13
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
14
15
#include "pari.h"
16
#include "paripriv.h"
17
BEGINEXTERN
18
#include "parse.h"
19
ENDEXTERN
20
#include "anal.h"
21
#include "tree.h"
22
23
static THREAD int pari_once;
24
static THREAD long pari_discarded;
25
static THREAD const char *pari_lex_start;
26
static THREAD GEN pari_lasterror;
27
28
static void pari_error(PARI_LTYPE *yylloc, char **lex, const char *s)
29
{
30
(void) yylloc; (void) lex;
31
if (pari_lasterror) cgiv(pari_lasterror);
32
pari_lasterror=strtoGENstr(s);
33
}
34
35
static THREAD pari_stack s_node;
36
THREAD node *pari_tree;
37
38
void
39
pari_init_parser(void)
40
{
41
long i;
42
const char *opname[]={"_||_", "_&&_", "_===_", "_==_", "_!=_", "_>=_", "_>_", "_<=_", "_<_", "_-_","_+_","_<<_", "_>>_", "_%_", "_\\/_", "_\\_", "_/_", "_*_","_^_","__","_--","_++","_-=_", "_+=_", "_<<=_", "_>>=_", "_%=_", "_\\/=_", "_\\=_", "_/=_", "_*=_","+_","-_","!_","_!","_'_","_~","[_.._]","[_|_<-_,_]","[_|_<-_,_;_]","%","%#","#_",""};
43
44
pari_stack_init(&s_node,sizeof(*pari_tree),(void **)&pari_tree);
45
pari_stack_alloc(&s_node,OPnboperator);
46
parsestate_reset();
47
for (i=0;i<OPnboperator;i++)
48
{
49
pari_tree[i].f = Fconst;
50
pari_tree[i].x = CSTentry;
51
pari_tree[i].y = -1;
52
pari_tree[i].str = opname[i];
53
pari_tree[i].len = strlen(opname[i]);
54
pari_tree[i].flags= 0;
55
}
56
}
57
void
58
pari_close_parser(void) { pari_stack_delete(&s_node); }
59
60
void
61
compile_err(const char *msg, const char *str)
62
{
63
pari_err(e_SYNTAX, msg, str, pari_lex_start);
64
}
65
66
void
67
compile_varerr(const char *str)
68
{
69
pari_err(e_SYNTAX, "variable name expected", str, pari_lex_start);
70
}
71
72
void
73
parsestate_reset(void)
74
{
75
s_node.n = OPnboperator;
76
pari_lex_start = NULL;
77
pari_once=1;
78
pari_discarded=0;
79
pari_lasterror=NULL;
80
}
81
void
82
parsestate_save(struct pari_parsestate *state)
83
{
84
state->node = s_node.n;
85
state->lex_start = pari_lex_start;
86
state->once = pari_once;
87
state->discarded = pari_discarded;
88
state->lasterror = pari_lasterror;
89
}
90
void
91
parsestate_restore(struct pari_parsestate *state)
92
{
93
s_node.n = state->node;
94
pari_lex_start = state->lex_start;
95
pari_once = state->once;
96
pari_discarded = state->discarded;
97
pari_lasterror = state->lasterror;
98
}
99
100
GEN
101
pari_compile_str(const char *lex)
102
{
103
pari_sp ltop=avma;
104
GEN code;
105
struct pari_parsestate state;
106
parsestate_save(&state);
107
pari_lex_start = lex;
108
pari_once=1;
109
pari_discarded=0;
110
pari_lasterror=NULL;
111
if (pari_parse((char**)&lex) || pari_discarded)
112
{
113
if (pari_lasterror)
114
compile_err(GSTR(pari_lasterror),lex-1);
115
else /* should not happen */
116
compile_err("syntax error",lex-1);
117
}
118
set_avma(ltop);
119
optimizenode(s_node.n-1);
120
code=gp_closure(s_node.n-1);
121
parsestate_restore(&state);
122
return code;
123
}
124
125
static long
126
newnode(Ffunc f, long x, long y, struct node_loc *loc)
127
{
128
long n=pari_stack_new(&s_node);
129
pari_tree[n].f=f;
130
pari_tree[n].x=x;
131
pari_tree[n].y=y;
132
pari_tree[n].str=loc->start;
133
pari_tree[n].len=loc->end-loc->start;
134
pari_tree[n].flags=0;
135
return n;
136
}
137
138
static long
139
newconst(long x, struct node_loc *loc)
140
{
141
return newnode(Fconst,x,-1,loc);
142
}
143
144
static long
145
newopcall(OPerator op, long x, long y, struct node_loc *loc)
146
{
147
if (y==-1)
148
return newnode(Ffunction,op,x,loc);
149
else
150
return newnode(Ffunction,op,newnode(Flistarg,x,y,loc),loc);
151
}
152
153
static long
154
newopcall3(OPerator op, long x, long y, long z, struct node_loc *loc)
155
{
156
return newopcall(op,newnode(Flistarg,x,y,loc),z,loc);
157
}
158
159
static long
160
countarg(long n)
161
{
162
long i;
163
for(i=1; pari_tree[n].f==Flistarg; i++)
164
n = pari_tree[n].x;
165
return i;
166
}
167
168
static long
169
addcurrexpr(long n, long currexpr, struct node_loc *loc)
170
{
171
long y, m = n;
172
while (pari_tree[m].x==OPcomprc)
173
{
174
y = pari_tree[m].y; if (countarg(y)==4) y = pari_tree[y].x;
175
m = pari_tree[y].y;
176
}
177
y = pari_tree[m].y; if (countarg(y)==4) y = pari_tree[y].x;
178
pari_tree[y].y = currexpr;
179
pari_tree[n].str=loc->start;
180
pari_tree[n].len=loc->end-loc->start;
181
return n;
182
}
183
184
static long
185
newintnode(struct node_loc *loc)
186
{
187
if (loc->end-loc->start<=(long)(1+LOG10_2*BITS_IN_LONG))
188
{
189
pari_sp ltop=avma;
190
GEN g=strtoi(loc->start);
191
long s = itos_or_0(g), sg = signe(g);
192
set_avma(ltop);
193
if (sg==0 || s) return newnode(Fsmall,s,-1,loc);
194
}
195
return newconst(CSTint,loc);
196
}
197
198
static long
199
newfunc(CSTtype t, struct node_loc *func, long args, long code,
200
struct node_loc *loc)
201
{
202
long name=newnode(Fentry,newconst(t,func),-1,func);
203
return newnode(Fassign,name,newnode(Flambda,args,code,loc),loc);
204
}
205
206
207
208