-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathreadme.txt
2377 lines (2238 loc) · 151 KB
/
readme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Phix readme.txt
===============
The windows installer (phix.setup.exe) defaults to C:\Program Files\Phix, though
you can change that. Alternatively you can use 7zip, and probably most other file
compression utilities, to extract the contents of phix.setup.exe, or equivalently
phix1.zip .. phix3.zip, to any directory of your choice.
**DEV**: this has changed with pdemo.exw and needs rewriting:
Installation does not modify anything in the system registry, nor does it create
any start menu or desktop shortcuts, or set the PATH environment variable.
The recommended post-installation setup is to manually associate *.exw files with
pw.exe using the "open with" option in Windows Explorer. Personally I never set
PATH, EUINC, or EUDIR, though they can be used if you want.
If using the windows installer, it should create pw.exe automatically for you.
However, you must manually inspect/run ppw.bat if extracting files by hand - it
is currently just 3 lines and the last line (p -c pdemo) is technically optional.
If you run "p -c p", to recompile the compiler from the supplied sources, then
it will create both a new p.exe and a new pw.exe, again automatically for you.
Please note the following entries are probably more for my benefit than yours.
Version 1.0.5
Version 1.0.3
=============
13/04/2023: Improved the compilation error reporting in the following case:
procedure p()
return true
^ may not change the value of a constant -- (new)
end function
--(old) ^ may not change the value of a constant
To achieve this, two new local variables atokline and atokcol are
now saved before invoking Assignment() in pmain.e (in one case,
quite wrongly, but not sure how that could be improved on, and
in fact merely replicating where it always used to be reported.)
28/06/2023: Improved the above error to "routine does not return a value",
in at least one patently incorrect instance anyway.
Version 1.0.2
=============
26/11/2021: Spurious C_PTR in demo\arwen\dll_links.ew caused a cryptic error
when running p -c edita, not that I have done anything to better
catch that in pmain.e, nor tested it still runs under Euphoria.
04/01/2022: Freed up the temp squence used in v.show(), using zero_temp().
06/01/2022: Prohibited switch/exit and loop/break under with js, see docs.
15/02/2022: Added some extra "unexpected end block comment" error checking.
While ptok.e/getToken() explictly checked for '*' and '/' after
"--" and issued an "unexpected end block comment" error, the same
was not true in the otherwise nearly identical code of ptok.e/
skipSpacesAndComments() which just let it pass by as an ordinary
(single) line comment. Of course it messed up syntax colouring in
the editor. It occurred inside a #ilASM{} and maybe that was the
only way it could have ever escaped unnoticed. Gave me a bit of
a fright, tbh, but probably won't trigger m/any knock-ons...
20/04/2022: Bugfix in p2js.js/$sidii(), which was doing s[idii[1]] = t; when
it should check for and add length(s)+1 to a negative idii[1].
13/05/2022: Bugfix: wrong era in :%pSubse1 (!!!, Decision tables) It would
not surprise me if that has to be hastily undone, but it looked
pretty clear-cut at the time.
06/07/2022: Bugfix: When compiled, the assert(j=3) failed after "for i,e in"
in t68forin, because "e" state updates clobbered the "i" state.
14/07/2022: Bugfix: switch <atom> [with fallthroughs detected] failing with
"cannot create jump table [swecode=14,...". Instead of checking
for slroot2!=T_integer, it now "not and_bits()" them.
28/09/2022: Bugfix: 1e18 was not generating an integer on 64bit. Rather than
(further) mess with %opPow in VM\pPower.e, I simply added a *10
loop in ptok.e/completeFloat() for (decimal) exponents 0..20.
Aka: integer i=1e18 <== "type error (storing float in integer)".
20/10/2022: Bugfix: for p in {po,pe} do was re-using the unnamed [tmp] var
in which {po,pe} was stored... There isn't really anything else
that needs to preserve an un-named var over a block, and in the
end I simply marked it as literal (opsltrl[2] = 1), realising
it being allowTempReuse (-1) was the core of the problem, and
0 (No) triggering an error in t68 (line 144). At the same time
I ditched a rather dubious looking bit of code that copied one
unnamed temp into another, for no reason I could think of.
20/10/2022: Bugfix/local constant restrictions: While you can still have a
locally scoped constant x = "one two three", attempting things
more complex such as constant y = split(x) was generating some
rather whacky compiler errors. On analysis, I realised that if
the routine was the target of a forward call, there would be
(even more than usual) difficulties, and nowhere sensible to
put the split() call, so I limited local constants to literals,
spat out a "not supported (sorry)" error, and updated the docs.
Ho hum, it seems the whole statics and local constants thing has
all been a complete and utter humiliating whitewash wipeout,
n'er mind. Probably would've been better as something like:
scope -- (named, maybe??)
constant y -- visible only in(/via) current scope
sequence x -- "", private variable but "static"
function/procedure()...
end function/procedure
end scope
24/11/2022: Bugfix: "type error (storing atom in sequence)" on s = {}&1,
and an internal crash on s = {}&{}. When optimising [multiple] &
into a single opConcat[N], it "assumed opApnd (alone) occurred",
which makes no sense, and in the second case tried to opConcatN
zero items, which ain't ever gonna fly. It now pushes an opMkSq
operation for <=1 items, as it always should have.
Version 1.0.1
=============
26/08/2021: Version 0.8.2 introduced an ill-conceived and pooly implemented
static routine-level declaration. It only ever worked for integers
and bools assigned to a literal or pre-existing file-level constant
(not parameters), and proved incompatible with p2js, hence the whole
sad and sorry mess was removed in the 1.0.1 release). Given the sheer
number of problems encountered when re-examined, I very much doubt it
saw any active service at all.
04/09/2021: Bugfix: "sequence avail" followed by "if avail(d) then", which should
of course been "if avail[d] then" was a) let through, and b) triggered
a truly horrid run-time error (typecheck in VM\pcallfunc.e which was
pretty ugly compiled, and out-of-symtab gibberish when interpreted).
It now says invalid routine_id(-8) but on a much more sensible line,
and if possible the compiler issues a "cannot be routine_id" error.
(The -8 is just a made up "not integer", alas I can do no better.)
06/10/2021: Added (optional) printf format subscript handling, for instance
printf(1,"%[3]02d/%[2]02d/%[1]04d",date()) is an easier way to
print a date without reordering and is particularly suited to the
(also) new format strings in an IupTable (example in docs).
30/10/2021: Bugfix: printf(1,"%d is %.1e\n",{150000,150000}) was (astonishly)
producing "150000 is 1.6e+5", instead of "150000 is 1.5e+5".
Added a (dicey) "fadj" tweak to clean up final digit handling.
25/11/2021:
1.0.1:
builtins\complex.e -- deep_copy rqd (bugfix)
builtins\dict.e -- putd forwarding "tid=1" instead of just "tid"
builtins\mpfr.e -- mpz_set_v, mpz_and, mpz_invert, mpfr_get_d_2exp, mpfr_const_euler
builtins\pApply.e -- now a proper p2js autotranspile
builtins\extract.e -- now returns string/sequence
builtins\pfactors.e -- new mpz_prime_powers() routine
builtins\pflatten.e -- join() now has an optional lastdelim parameter
builtins\pipeio.e -- windows-only named pipe routines, not yet documented,
-- and will remain so until they also work on Linux.
builtins\ppp.e -- pp_IntCh now defaults to false, so you get 65 not 65'A'.
builtins\prnd.e -- new rand_range() function
builtins\punique.e -- made p2js compatible
builtins\sockets.e -- closesocket() now a function
builtins\sort.e -- sort_columns() needed a deep_copy()
builtins\to_int.e -- to/is_integer() now have optional base=10 parameter
builtins\unit_test.e -- made p2js compatible
builtins\VM\pcall(/pc)func.e -- safe_mode mods
builtins\VM\pDiagN.e -- disable safe_mode on crash
builtins\VM\pprntfN.e -- %[idx] subscripted arg handling (see docs)
-- eg/esp print a date() w/o having to reorder it.
new builtins\glmath.e
new builtins\hmac.e
new builtins\IupGraph.e
new builtins\IupRawStringPtr.e -- (moved out of pGUI.e for safe mode handling)
new builtins\opengl.e -- (stub link to demo\pGUI\opengl.e)
new builtins\sha1.e
new builtins\sha512.e
new builtins\unix_dict.e -- (mainly for the benefit of p2js)
new demo\pGUI\HelloF.exw -- proper desktop/WebGL demo
new demo\pGUI\opengl.e
demo\pGUI\IupSampleDialog.exw -- much work to do, but slowly getting there
demo\rosetta\15_puzzle_game_in_3D.exw -- p2js compatible
for loop vars are now "resurrected" rather than replicated in the symbol
table, which means you no longer get ex.err files with 17 'i' entries.
new eval() function, see docs (if you don't like it, tough)
significant updates to OpenGL/WebGL docs
IupGetAttribute() now has a default, mainly for the benefit of p2js
IupGetBrother() now has a bPrev parameter, to get previous element
IupGetIntInt() added
IupTable: data[2] can now contain simple format strings
"with safe_mode" and/or "p -safe" for running untrusted code
join() now has optional override for last delimiter, eg ", and "
p2js: replaced all use of charCodeAt() with codePointAt()
"static" deprecated (it never worked anyway)
"continue" is now officially deprecated, although it still works
(As Douglas Crockford says "I have never seen a piece of
code that was not improved by refactoring it to remove
the continue statement.", and I have to agree.)
pwa\p2js.js : replaced factors/sum/product/find/match/apply with their
auto-transpiled versions, added dummy utf8_to_utf32 and
utf32_to_utf8.
pwa\pGUI.js : more changes than you can shake a stick at, including:
IupsetGlobalFunction(IDLE_ACTION), IupS/GetAttributeId(list_id),
IupSetAttributePtr, IupSetDouble, IupSetAttributeHandle(MENU),
IupSetCallbacks, IupClipboard(?), IupRefresh[Children], IupText,
IupSetFocus, IupGetChild[Count], IupGetClassName, IupGetFocus,
IupGetDialogChild, IupGetParent, IupGetBrother, IupDatePick,
IupFlush, IupFrame, IupList, Iup[Sub]Menu[Item], IupSeparator,
IupMultiBox, IupProgressBar, IupSplit, IupTableGetSelected,
IupTableClearSelected, IupTableClick_cb, IupTabs, IupRadio,
IupValuator, [[hsv_]to_]rgb, cdCanvasActivate, cdCanvasPixel,
cdDe/EncodeColour[Alpha], cdCanvasArc/Sector/Chord/Circle/Clear/
Flush/Font/GetSize/GetImageRGB/Line/[Rounded]Box/[Rounded]Rect/
SetAttribute,SetFore/Background,SetFillMode,S/GetInteriorStyle,
SetLineStyle/SetLineWidth/Text,SpecialText,S/GetTextAlignment,
GetTextSize,S/GetTextOrientation,VectorText[Direction/Size],
IupTimer,glAttachShader..Viewport, IupDraw*,
and adding but completely messing up the resize handling...
Version 1.0.0
=============
03/02/2021: Bugfix: IupMessage crashed if msg was NULL. Added bWrap option to
both IupMessage() and IupMessageError().
04/02/2021: Bugfix: User defined types within classes not working. Given say
class Element Ihandle handle, the "Ihandle" was being pushed via
addUnnamedConstant(), when it obviously needed addRoutineId().
04/02/2021: Bugfix: delete_routine(x,0) was not removing the routine.
04/02/2021: Icallback() was creating multiple instances of a callback, even
though it was keeping (3) tables to avoid precisely that...
Not a big deal, since call_back(), which obviously Icallback()
wraps, already checked for and re-used prior instances anyway.
07/02/2021: Bugfix: unique(x,STABLE) was not using the dictionary tid, and
hence returning the entire original list... Belated test added.
16/02/2021: Fixed trace on linux
17/02/2021: Enhancement: Added a hll goto statement, and documented it.
18/02/2021: Created builtins\pipeio.e from guts of demo\capture_console.exw
23/02/2021: Moved && and || up the precedence table above relops, matching
Python and now disagreeing with C/JavaScript. For example,
a && b != c was a && (b != c), but is now (a && b) != c. Note
a and b != c is however still a and (b != c). t66 tweaked.
03/03/2021: vslice() can now accept a pair of column indices, so it can now
take an actual slice as it always should have been able to.
(Needed/wanted for a rewrite of demo/rosetta/viewppm.exw)
23/05/2021: Removed the pointless restriction that rid() only worked when
rid was specifically of type integer, which means you can now
do things like s[FUNC](1,2,3) - and of course we can rely on
call_func/proc() to crash when s[FUNC] ain't an integer/rid,
so it is not about to "do weird things" as initially feared.
Version 0.8.3
=============
22/12/2020: Bugfix: "class x string name procedure name()" now produces the
error "invalid type". Note that all methods are "virtual" in the
sense they can be overidden, ideally it would check that it was
only overriding something from an "extends" clause, but that is
not particularly simple. Instead it is saying it cannot override
a string with a procedure. Likewise it will trigger an error if
you try to override a procedure with a function and vice versa.
I would have liked to put signature checks in there, but alas
that information is not held (think "pure virtual"), or rather
it is quite a bit more difficult to dig out.
24/12/2020: BUGFIX: in something (well, anything!) like the following
sequence x = repeat(0,rand(50))
if <condition> then
x = {} -- (or any other [fixed] length)
end if -- <<== **bad mergeBlocks()/mergeTypes() here !!!**
if length(x)=0 then ?9/0 end if -- <<== uses if 0=0 then!!
pltype.e was replacing/merging the lslen[prev] of -1 (aka
"no idea yet") with the lslen[curr] of 0, which meant it would
think x was length 0 (or whatever) even after condition failed.
It now leaves it alone (the last if now /looks/ at x's length).
Amazed this was not caught years ago, and even more amazed that
p -test didn't start /any/ bitchin...
02/01/2021: Replaced sys_exit with sys_exit_group, for proper linux s/down.
08/01/2021: Moved initialisation in sha256.e to permit forward calls.
10/01/2021: Added hideScope/restoreScope for nested functions, which hide
anything and everything that would otherwise require a closure.
Note that some work remains outstanding in this area.
21/01/2021: Tightened up on builtin overrides, to prevent such nonsense as
integer integer, atom atom, string string, and so on. constant
SLASH was a bit of an innocent bystander, though you/I should
probably be using the builtin constant anyway.
21/01/2021: BUGFIX: Ctrl [] in Edita/Edix now correctly skip backtick strs.
21/01/2021: Edita: easinst.ew now uses GetWindowText, should be better.
21/01/2021: BUGFIX: Edix now uses an ini file rather than IupConfig for the
list of open files, which was always corrupting itself. Close
file now works properly, not mangling the table of tab handles.
25/01/2021: IupCloseOnEscape() is now applied by default to all IupDialog,
and the latter has a new bEsc parameter to turn that off.
25/01/2021: get_routine_info() now has a bName parameter, which will avoid
unnecessarily populating the symbol table with actual names.
25/01/2021: ENH: IupScintilla() added to pGUI, along with a demo.
29/01/2021: BUGFIX: deleting a dictionary entry was moving the key but not
the data(!!). Many thanks to irv for finding this nasty bug.
29/01/2021: New still_has_delete_routine() function. Used by the internal
type checking routines of builtins\structs.e to identify any
now-invalid struct/class instances, and prevent accidentally
clobbering a slot now occupied by something else.
30/01/2021: BUGFIX: tagset was using ceil() not floor() for some unknown
reason, and thus overruning the limit (when step!=1).
01/02/2021: ENH: allow dot notation on "struct" variables (previously it
only allowed that on actual struct/class definitions). Eg/ie
-- procedure test(Widget x) -- (was ok)
procedure test(struct x) -- (now ok too)
x.field = 1
end procedure
01/02/2021: Allowed delete_routine(x,0) to remove any prior association.
The docs said you could, but the front-end disallowed it.
Version 0.8.2
=============
22/05/2020: You can now say pMem = free(pMem), setting pMem to NULL. While
free() is still a procedure, there is a new function ffree()
which returns appropriate NULLs and pmain.e now quietly maps
free() calls to ffree() instead of issuing an error.
06/06/2020: Removed backtick from Delimiter section of FASM.syn - I have
no idea why/when it got put in there. Improves viewing of
list.asm files, and hopefully does not break something else.
08/06/2020: Added a find_all() builtin (documented alongside find()).
Make builtins\ordinal.e an auto-include, why not.
18/06/2020: Added a simple assert() builtin, see crash() docs.
20/06/2020: Made serialize() return a binary string, rather than a
dword-sequence.
20/06/2020: Nested constant declarations, eg instead of
constant WSAEINTR = 10004,
WSAEACCES = 10013
constant {ERROR_NO, ERROR_NAME, ERROR_SHORT} = columnize(
{{WSAEINTR, "WSAEINTR", "Interrupted function call."},
{WSAEACCES, "WSAEACCES", "Permission denied."}}
(which gets more and more error prone and tedious as the table
grows in size) you can now define them all together like this:
constant {ERROR_NO, ERROR_NAME, ERROR_SHORT} = columnize(
{{WSAEINTR:=10004, "WSAEINTR", "Interrupted function call."},
{WSAEACCES:=10013, "WSAEACCES", "Permission denied."},
ie on the second line before the first ',' we see both a definition
of WSAEINTR and a reference to it.
25/06/2020: Added pp_IntCh of -1 handling to show eg 65 as just 'A'.
26/06/2020: HACKFIX. An "if atom(data) then" which was being optimised away
was invoking an ltAdd(TEST+flippable,..) in pilx86/opJtyp which
was never getting undone/flipped. For now, I simply removed it,
which means it will now properly test a few things that it was
previously optimising away. This may need to be revisited.
(For some failing example code see end of test/t37misc.exw.)
28/06/2020: New faster version of is_prime(), now moved to pfactors.e.
28/06/2020: Added apply() and filter() routines, plus get_routine_info().
28/06/2020: BUGFIX: Named parameter handling error on auto-includes, eg
?shorten(s,ml:=2)
^ incompatible type for routine signature
In this particular case/call it now effectively/temporarily
overrides the psym.e signature from "FPSI" to "FPOO". It may
prove better to replace that sig = T_object just added to
pmain.e/ParamList() with an outright rejection along the
lines of Aborp("named params require explicit include"),
which you can find commented-out/untested in ParamList().
[Or, of course, shove a gazillion and one tons of code into
psym.e to handle named args on autoincludes, and builtins..
but I think I'd rather start a brand new Phix 2.0.........!]
27/08/2020: BUGFIX: eax trashed by belayed opScmp: Expr() now has an extra
saveFunctionResultVars(opsidx,INTSTOO) call (see t37misc).
27/08/2020: BUGFIX: a literal -1073741824 was getting T_N not T_Integer.
08/10/2020: BUGFIX: printf(1,"x%04dx\n", -1) was yiedling "x00-1x". It
now yields "x -1x", whereas Euphoria yields "x-001x", which
I suspect is down to the underlying C implementation and may
not even be constent between platforms. I may be persuaded
to attempt futher tweaks to improve compatability should
anyone kick up a big enough fuss about it..
10/10/2020: BUGFIX: without debug {include} with debug was not properly
re-enabling top level diagnostics on the current file, so
effectively without debug would continue to apply to all
top-level code after the with debug statement. The flag is
binary, btw, you can't turn it off for half the top-level
code, but obvs you shd be able to turn it back on for the
current file, after hiding some builtins from the ex.err.
Subroutines after the with debug were however always fine.
01/11/2020: BUGFIX: Nested constants were not properly marked as such,
eg SPREAD in p2js_basics.e - triggering the compilation
error "cannot create jump table" on a switch statement
(since to do so all targets must be known at compile-time,
and that will be forced by any "fallthrough" statements).
05/11/2020: BUGFIX: Embedded classes were using the stids rather than
the srids in struct_add_field(). This meant that several
test cases worked fine interpreted, but crashed with an
invlaid routine_id when compiled.
15/11/2020: BUGFIX: switch length(r) do was suppressing the store of
tmp in tmp=length(r), leaving it in a register, then in
"if tmp=1, elsif tmp=2..." the first tmp was correctly
getting the register, but second (etc) "reloading" tmp.
Quite probbly, the real bug was that reginfo was not
being correctly maintained, but instead I simply killed
pilx86.e/transtmpfer() [maybe I could have limited that
damage to IF], and luckily there didn't appear to be any
significant performance hit, but time may yet tell...
16/11/2020: Enhancement: added %q and %Q to (s)printf(), which are
like %s but add quotes. %q can use backticks, and favours
them if the new "prefer_backtick" option is set, whereas
%Q forces doublequotes. Moved (s)print() from their old
builtins\VM\psprintN.e home to builtins\VM\pprntfN.e,
so that the internal allascii() could be shared/tweaked.
17/11/2020: Added Edix\syn\css.syn to syntax-colour .css files, obvs.
Be warned it thinks \\ is a css line comment (none such).
Feel free to copy it to Edita\syn, but I'm not going to
bother with maintaining and shipping two copies of it.
Version 0.8.1
=============
01/05/2019: Made mpfr.e check for existence of msvcp100.dll/msvcr100.dll.
Also made mpir_get_versions() 64-bit compatible and work when
mpir_only is in force, fixed mpz_mod_ui() [obviously it had
never been tested], added mpz_fdiv_qr() and fixed a bug in
mpz_get_str() whereby it crashed with a stack overflow when
printing >~100K digits (it now prints in chunks of 20K digits
and stitches them together).
01/05/2019: Minor bugfix in timedate.e for length(td)<DT_TZ.
01/05/2019: Removed thousands of valign=top from the docs since it made
no difference to the chm but messed up the online docs.
08/05/2019: Added get_file_date() and set_file_date(), and added an optional
date_type parameter to dir().
09/05/2019: BUGFIX: [sequence] tasks = extract_tasks(tasks) was not checking
for tasks being unassigned properly (==> [MEMORY VIOLATION]), if
the pass-by-reference optimisation was being applied in opFrst.
Arguably on declaration the front-end should spot such and issue
a fatal compilation-time error [DEV]. It would also benefit from
popping an opFrame before triggering the fatal runtime error, to
prevent the spurious "(warning: lineno of -1 for era of #HHHH)".
22/05/2019: BUGFIX: The internal routine timedate.e/timedate_to_julian_day()
was returning the same day for 28/2/2034 and 1/3/2034. There was
already a different algorithm from wikipedia commented out which
claimed to return the same results: it didn't, and has now been
adopted as the better algorithm, fixing the above problem.
25/05/2019: ENH: throw("could not open "&dll_name) was reporting the error as
"unhandled exception", it now checks for the "plain string" case
and says eg "unhandled exception (could not open kerbnel32.dll)"
(that is, when you have accidentally spelt kernel32 with a 'b').
03/06/2019: More thread-safety mods to VM\prntfN.e (see OEforum).
17/06/2019: Added sprintf() functionality to throw().
19/06/2019: Added several dozen more routines to mpfr.e. Added try/catch to
the core types. Added mpz_add_si, mpz_sub_si, mpz_odd, mpz_even,
mpz_sign, mpz_remove, mpz_prime_factors, mpz_factorstring, and
mpz_re_compose.
Removed mpz_fits_s[/u]long_p, added mpz_fits_integer[/atom].
Removed mpz_get_s[/u]i, added mpz_get_integer[/atom].
Obviously the replacements are geared towards the phix limits,
ie 31/53/63/64 bits, rather than the machine word / C limits.
Allowed mpfr_set_default_prec and mpfr_set_prec to accept a -ve
decimal precision (as well as the existing +ve binary precision).
21/06/2019: Bugfix: emitHex10sdi() did not have any proper handling for large
64-bit integer literals, eg anything > #FFFFFFFF.
22/06/2019: Added pp_IntCh to ppp.e and deprecated several pp_StrFmt settings:
-2 => use {pp_IntCh,false} instead
-3 => use {pp_StrFmt,-1,pp_IntCh,false} instead
1 => use {pp_StrFmt,3,pp_IntCh,false} instead
(I went the extra yard to give properly helpful error messages.)
pp_IntCh means display integers as eg 65'A', default true, and
obviously set it to false when you only want the 65 part.
[This change adds no functionality, just makes things clearer.]
22/06/2019: Make ppp.e use backticks rather than doublequotes + escapes, when
that seems to be the sensible thing to do. Ditto ex.err files.
23/06/2019: Bugfix: looks like I was mapping TCHAR the wrong way round in
cffi.e, and ansi was getting treated as UTF-16. Oops.
08/07/2019: Bugfix in Edita/edx: Pascal block comments ({"{","}"}) were not
working. Traced to chidx2 -= 1 before the first scanForUrls()
call in [ea]synclr.e which has been removed. Obviously it seems
ok, but there may be some unexpected knock-on effects.
16/07/2019: Added pipes parameter to system_exec(), and demo/capture_console
to demonstrate use. Needs a bit more work on linux.
22/07/2019: Enhanced scanf() to properly handle %b/o/x formats. Previously
it could scan "#DEADBEEF" but not "DEADBEEF", now it can do both.
At the same time, to_number() was given an optional inbase param.
31/07/2019: BUGFIX: scanf() was not parsing floats/checking for '.' correctly.
02/08/2019: Added and_bitsu(), ditto not/or/xor, which give unsigned results.
07/08/2019: ENH/BUGFIX Invoking free() on a value with delete_routine() in force
now behaves as delete(). It is assumed it will re-invoke free(), but
of course with the routine field as just zeroed. Previously, calling
free() on such would often result in a cryptic fatal error, as the
subsequent delete() would re-invoke free() with the same address.
12/09/2019: ?`"abc"` now prints `"abc"` rather than "\"abc\"". If a string has
any of "\r\n\t\0\e" then doublequotes\backslash must still be used,
but if not, yet some of "\\\"\'" (aka `\"'`) /are/ present, then it
uses backticks instead of dblquotes. See builtins\VM\psprintN.e
12/09/2019: Upgraded pGUI libs to 3.27, which went without hitch.
19/09/2019: BUGFIX: /0 on pltype.e line 678, procedure ltAdd(). Caused by the
(udt) "boolean wild_str = find('?', str) or find('*', str)" in
demo\search.exw, dltyp[=976]!=ptyp[=1]. It now checks that both
are <=T_object before complaining.
21/09/2019: BUGFIX: peek({mem,0}) on 64-bit was doing a sub rsp,8 which should
have been an add rsp,8 (to match the 32-bit add esp,4). That little
beastie of a bug was apparently introduced on 23/5/15!
27/09/2019: BUGFIX: unconditional exit from for loop: reversed the changes of
25/10/2017 (see below), which resurfaced. It occured to me (and I
have no idea why not 2 years ago) that the backpatch could probably
also be done in jskip() [as well as opEndFor], which it now is.
Note there may be some uses of jskip() which do not set "mergeSet"
properly, which it now relies on.
25/10/2019: BUGFIX: A statement such as board = repeat('+'&"x",2) incorrectly
changed opRepeat to opRepCh (or more accurately routineNo from
T_repeat to T_repch in pmain.e/ParamList()), leading to strange
and random output, as it brutally coerced parameter 1 to char using
the asm equivalent of and_bits(<ref of string "xx">,#FF), and also
a fatal crash on line 3370 in pilx86.e/StoreDest() on finding a
string with string elements/characters. It now checks not just for
a toktype of SQUOTE, but also a following Ch of ','.
27/10/2019: ENH: Made routine_ids first class, ie [also] callable directly. Eg:
procedure show(string s) ?s end procedure
constant r_show = routine_id("show")
-- show("40") (normal non-routine_id call [still valid!])
call_proc(r_show,{"41"}) -- old style [""!]
r_show("42") -- ***new***
function f(integer i) return i end function
constant r_f = routine_id("f")
--?f(40) (normal non-routine_id call [still valid!])
?call_func(r_f,{41}) -- old style [""!]
?r_f(42) -- ***new***
Any integer followed by '(' is treated as a call_func() or a
call_proc(), depending on the context, and obviously as above
the normal/old styles remain perfectly valid and fully supported.
However I decided against supporting this sort of thing (at least
not before someone comes up with a compelling reason to):
--?r_f(r_f)(43)
--r_f(r_show)(44)
--sequence rids = {r_show}
--rids[1](45)
Instead you have to code integer rid=r_f(r_f) then ?rid(43), etc.
(Some wag might say that makes them second class, but it is not
like you could ever do anything like that with "show" anyway.)
Note that i(5) where i is not a routine_id will fail just as badly
and in exactly the same way as call_func/proc(i,{5}) always has.
Likewise the additional compile-time validation of argument types
is not performed/deferred until run-time, in exactly the same way
as it always was for explicit/old-style call_func/proc() calls.
These changes were made to complement the syntax enhancements for
the new struct/class handling, specifically class methods.
22/11/2019: Added builtins\ordinal.e (not an autoinclude):
ord(i) returns "st", "nd", "rd", or "th".
ordinal(n) returns "first", "second", etc.
ordinal(n, bJustSpell:=true) - returns "one", "two", etc.
23/11/2019: Added an explicit string(cl) check to ppp.e, since I simply never
want to see {"this",{9,10}} as {"this","\t\n"} ever again... if
it causes any grief, I guess I'll have to make it optional.
25/11/2019: [EXPERIMENTAL] added simple lambda function support. You can now
integer rid = function(integer i) return i+1 end function
?rid(3) -- (as per 27/10/2019 above, nowt changed today.)
Not entirely sure where this is heading. The "integer rid =" is
not the interesting part, the inline function on the rhs is.
Such functions would need an explicit self_rid to be recursive.
A single-statement equivalent might also be possible, such as:
integer rid = =>(integer i) return i+1 -- (or "==>"?)
The body could also be any single statement (if/for/while/try as
well as return, but not an unwrapped block), with caveat emptor
should it exit instead of an inner [explicit] return. However I
should probably wait until I find an actual use for the longhand
form before I start designing a shorthand form!
**NB** the expression does not yet have any access to the nested
scope, I just realised, making it rather somewhat less useful...
Left as is for now, need to get demo\rosetta\Nested_function.exw
working before anything else can be done here.
Also [DEV] this remains undocumented, apart from here.
28/11/2019: BUGFIX (bitbucket issue #27, rmatch length 1 not working.) There
was a completely spurious "ln -= 1" on line 164, such that if you
sought "xyz" it would actually find "xy", and in the length of 1
case, the ensuing for j=1 to 0 loop never successfully returned.
05/12/2019: BUGFIX: power(i,3) emitted mov ecx,3; mov eax,ecx; call %opPow;
so everything came out as 27. It now calls clearReg(ecx) which
makes it emit the more correct and useful mov eax,[i] instead.
11/12/2019: Added %t to (s)printf(), to print "true"/"false" from a boolean.
11/02/2020: To complement first class routine_ids, the absence of a trailing
'(' makes a routine reference equivalent to its routine_id, eg
atom eThread = create_thread(routine_id("mythread"),{1}) is old,
atom eThread = create_thread(mythread,{1}) is now the same. Nice.
Note that some builtins such as length still have no routine_id,
and instead you must provide you own mini-shim for such things.
[update: fixed in 0.8.2 via autoinclude builtins/hll_stubs.e]
12/01/2020: day_of_week() changed to return 1..7 (Mon..Sun) [was Sun..Sat]
(bringing it into line with ISO 8601 and the earlier ISO 2015)
13/02/2020: Added include_file[s]() to match include_path[s](), see docs.
Version 0.8.0
=============
17/08/2018: BUGFIX: delete_routine() was not setting refcounts or even storing
the result correctly. res = delete_routine(res,rid) would work, but
tmp = {a,b}; res = delete_routine(tmp,rid) (and the same when tmp
was an unnamed temporary variable due to inlining the {a,b}) would
leave res either completely unassigned or with its prior value.
24/08/2018: BUGFIX: DoForwardDef() was declaring function returns as Private
rather than FuncRes, leading to saveFunctionResultVars() not being
called for routines (such as ba_sub) that had an explicit forward
definition, producing garbage results. Trivial fix, once found.
02/12/2018: BUGFIX: sprintf("%f",2e-77*1e100) yeilded "1:000...". The ':' is
from '9'+1, it is kind of trying to print 19999... (which is fine,
if we end up with >5 left over we run back down, rounding up), but
instead of a 9 for the 2nd digit it got a 10. Clearly such values
are quite rare, eg the apparently equivalent 2e23 does not exhibit
the same problem. Added a second test "if digit=10 then exit" and
an "or digit=10" to round_str().
12/01/2019: Added %v to [s]printf(), which is %s with a sprint(), and can
therefore be used to print [almost] anything. Note however that
bigatoms will show the bcd-internals, and bigints the base-65536
internals, etc, so it ain't perfect [yet...].
29/01/2019: "and board[i+direction][j+move] == iff(move=0?'.':opponent) then"
failed in pmain.e/DoIff() as exprBP was not zero, as already noted
in the comment which read "we may yet have a problem..." next to
it. Trivial fix, just save/restore exprBP (and scBP, why not).
15/02/2019: BUG: the type text_point() in builtins/pscreen.e was checking for
{300,500}, inherited from a {200,500} as found in OE's image.e,
however I had at some point resized my terminal to {500,271}. It
now checks for {65535,65535}. However, the problem was originally
triggered via a trace(1) in pilx86.e when running "p p -d e01",
ie typecheck within pTrace.e as compiled into p.exe, which simply
confused the bejesus out of pDiagN.e, as none of the addresses
corresponded to the symtab of p.exw... and it still would ...
What I think it needs to do is check for addresses in the region
of symtab[20=optable] or something like that, and (temporarily)
use a "lower-level" symtab from symtab[T_EBP][3] (as set in p.exw,
potentially recursively), or somesuch. [DEV/TODO]
25/02/2019: BUGFIX: the try statement had absolutely no localtype handling, as illustrated
by the following code which compares said against an if construct:
integer q, q11, q22, q12, r, r11, r22, r12
if rand(2)=1 then
q = 1
q11 = q
else
q = 2
q22 = q
end if
q12 = q
?q
try
r = 1
r11 = r
catch e
r = 2
r22 = r
end try
r12 = r
?r
#isginfo{q,integer,1,2,object,-1}
#isginfo{q11,integer,1,1,object,-1}
#isginfo{q22,integer,2,2,object,-1}
#isginfo{q12,integer,1,2,object,-1} -- good!
#isginfo{r,integer,1,2,object,-1}
#isginfo{r11,integer,1,1,object,-1}
#isginfo{r22,integer,2,2,object,-1}
--#isginfo{r12,integer,1,2,object,-1}
#isginfo{r12,integer,2,2,object,-1} -- oops!
If you ran that code, r would always be shown as 2, despite no exception ever occuring
(and in fact an ex.err would contain 1, but the compiler still insists it must be 2).
The above code is now permanently part of test/t49ginfo.exw, with "if r12=2 then ?9/0".
The localtype information (which includes min/max as well as type) was not being properly
reset at "catch" and merged at "end try", in the same way it is at "else" and "end if",
and obviously similar mechanisms also exist for "for/while" .. "end for/while", which
turned out to be the more suitable to repurpose when fixing this particular issue.
Note that the il now generated re-uses opLoopTop and opCtrl,END+LOOP, something like:
try
-- opLoopTop,lmask,gmask,elnk
-- opTry,tmp,tgt
...
-- opCtrl,END+LOOP,link,emitline
-- opTryend,0,149,0,96,
catch
-- opLoopTop,lmask,gmask,elnk
-- opCatch,tlnk,e
...
-- opCtrl,END+LOOP,link,emitline
end try
-- opLabel,mergeSet,0/x86loc,link
(obviously I have used poetic licence and moved "catch" down two lines for clarity)
(and obviously them not loops, just blocks that need the same reset/merge handling)
Apart from the "that's always 2", the actual machine code is otherwise unchanged.
There is an untried and commented-out TRY constant in pltype.e, but replicating
opLoopTop as, I dunno, say, OpTryBlock seems like far too much effort for the
rather scant reward of slightly easier to read ildump.txt files.
I also added clearIchain() to DoTry(), to reset any "known to be initialised" flags.
08/03/2019 BUGFIX: Crash in pmain.e/DoIff() compiling the following:
integer i = rand(10)
bool doit = iff( false ? i>=5 and i<7 : i>5 and i<=7 )
Turns out it had never handled any and/or inside an iff() expression properly.
Simple fix was just Expr(0,0) ==>> Expr(0,asBool), times two, in DoIff().
20/04/2019: Other changes in the 0.8.0 release:
Installation now in three parts, phix.0.8.0.setup.exe, phix.0.8.0.1.zip, and
phix.0.8.0.2.zip. The setup.exe automatically downloads (unless it can find them)
and extracts the two .zip files (via demo/pGUI/pdemo/installation.e).
NEWGSCAN (disabled for now)
GetLastAccessTime() renamed as GetFileTime() in builtins/timestamp.ew
get_text() now supports GT_KEEP_BOM, and GT_WHOLE_FILE now only adds a trailing \n
when the file has been opened in text mode (ptok.e changed to do that to match).
log2() added
de/encode_base64() documented and builtins/base64.e made an auto-include.
custom_sort() enhanced to support inline tagsorts w/out custom comparison routine,
and now also supports both ascending and descending modes.
sort_columns() added
extract() and reinstate() added
include_path() added (without an s) to complement/filter include_paths()
set_file_size() added, and get_file_size() can now return a KB/GB/TB string result.
sq_min(), sq_max(), and sq_log2() added
allow_novalue() added to bigatom.e
ba_sprintf() can now comma-separate the integer part of the result, like sprintf().
New aliases ba_div, ba_idiv, ba_mul for ba_divide, ba_idivide, and ba_multiply.
New routines ba_factorial, ba_gcd, ba_lcm, ba_mod, ba_mod_exp, ba_sign, and ba_uminus.
pretty_print() moved to builtins/pretty.e and documented (was in misc.e)
new_dict() can now make a fast copy of an existing dictionary
factorial() now iterative (and hence slightly faster, was recursive)
lcm() added to complement gcd()
builtins\xml.e added, for converting xml text <==> nested structure, and documented.
builtins\mpfr.e, a wrapper for gmp, for fast [very fast] arbitrary precision maths.
(^note the dlls still need to be downloaded manually for now, but I have a plan..)
builtins\pSQLite.e added, see (extensive) new documentation under Other Libraries.
regex now supports h/v/z for horizontal whitespace, vertical whitespace, and eof.
[s]printf() now has text centering, v for sprint(), unicode alignment now optional.
new error "attempt to get square root of negative number" in the sqrt() builtin.
builtins\prnd.e is not yet used and should be ignored for now.
rmatch() added to complement match(), as per OE, matches from the other end.
proper() added to builtins/pcase.e - not yet documented [now done, 1/1/20].
builtins\complex.e added for complex number handling - not yet documented.
builtins\pfrac.e added for rational fraction handling - not yet documented.
builtins\pqueue.e added for priority queue handling - not yet documented.
OE compatibility routines lookup(), keyvalues(), text_format() and begins() added
to builtins/pvlookup.e, not yet documented.
builtins now has ripemd160.e and sha256.e, not documented, not likely to ever be.
ditto builtins/unicode_console.e
Version 0.7.8
=============
10/01/2018: BUGFIX: when the file/directory is not found, apply get_proper_path()
recursively to the parent directory.
21/01/2018: BUGFIX: rand() effectively preserved the high bit for ranges over
#7FFFFFFF. Changed a jge (signed jump) to jae (unsigned).
Also changed the 64-bit store to deal with 64-bit results above
#7FFF_FFFF_FFFF_FFFF correctly.
03/02/2018: Corrected definition of xGetExitCodeThread.
15/02/2018: New LiteZip wrapper and documentation added.
15/02/2018: BUGFIX: Slice replacement was out-by-one, eg
s = { 1,2,3,4,5,6 }
s[1..1] = 9
was incorrectly {9,1,2,3,4,5}, now yields {9,2,3,4,5,6}.
Thanks to Tom for finding this.
17/02/2018: Bugfix: parse_json() did not cope with negative numbers.
Thanks to Chris for finding this.
17/02/2018: Bugfix: setup.ew crashed for registry keys of length 0.
Thanks to Kat for finding this.
20/02/2018: Removed spurious sanity check in change_timezone().
Thanks to Chris for finding this.
24/02/2018: =$ can now be used anywhere except the first in an enum.
Previously =$ only worked for delta==+1, but DoEnum()
now has a prev var, so that any "by delta" now works.
28/02/2018: Added peek_wstring() and poke_wstring().
04/03/2018: adjust_timedate() no longer clobbers DT_MSEC aka DT_DOW.
05/03/2018: timedate.e: added "ms" to extract/print milliseconds.
(not thoroughly tested, possible ambiguity issue noticed)
06/03/2018: constant integer {a,b} = <expr> style syntax now supported.
06/03/2018: date(DT_GMT) now returns the GMT (==UTC) time, irrespective
of location, with milliseconds.
14/03/2018: Fixed potential thread safety issue in sprint().
14/03/2018: Upgraded to IUP 3.24. Three routines have been removed:
IupColorbar, IupColorBrowser, and IupDial.
Version 0.7.5
=============
22/02/2017: BUGFIX: task_yield() was incorrectly defined as E_other in psym.e,
it is now correctly defined as E_all. Correspondingly, the #ilASM
in the routine itself was missing an e_all directive.
07/03/2017: BUGFIX: ltAdd() was reusing a SET entry, causing problems:
integer froot
procedure digital_root()
integer root = 0
while 1 do
root += 1
if root<froot then exit end if
root = 0
end while
froot = root
end procedure
froot = 10
digital_root()
The root=0 SET was overwriting the +=1 SET, causing it to think
that root must be 0 after the end while. I just rudely deleted
the whole attempt to reuse SET entries... (fingers crossed)
16/03/2017: BUGFIX: s[i][$] = 'x' completely broken when s[i] was a string.
:%opRepe was jumping to :RepeStr /before/ calling :%fixupIndex
17/03/2017: Renamed the "unicode" library as "utfconv" in the manual, as
more logical, and to match the name of the (auto)include file.
17/03/2017: Bugfix: adjust_timedate() crashed if delta was not a whole number
of seconds. Also, timedate_diff() was ignoring milliseconds, and
date() now optionally returns milliseconds.
19/03/2017: Now supports the following Orac idioms:
s.i as shorthand for s[i]
s.i.j as shorthand for s[i][j]
[i to j] as an alternative to [i..j]
~s as shorthand for length(s)
int, seq as shorthand for integer, sequence
(disable if required by setting constant ORAC in p.exw to 0)
Edix\tools\reindent has been updated to support these, but I
don't plan to backport that to edita (feel free, just look on
bitbucket for a diff around this date to edix\src\rein.e and
try to make the equivalent changes to edita\src\earein.e).
21/07/2017: Bugfix: pilx86/opPow could emit overwrite edi==tmpr; in this
particular case res = power(x,length(d)) was effectively the
same as res = power(x,<raw addr of res>), obviously leading
to power overflow errors. (60 second fix)
29/03/2017: Bugfix: cdx = find(cemi,"CEeMm")-(cemi='m') was invoking find(), leaving
the result in eax, then invoking opSeq to set eax (as cemi=='m'), then
subtracting eax from eax, and therefore always setting cdx to 0.
It now invokes saveFunctionResultVars() in pmain.e before trashing eax.
03/01/2017: Enhanced integer powers. Previously, (on both 32 and 64 bit) it would
calculate power(-177..+177,1..4) in eax/rdx. It now uses two ranges:
32-bit: +/-181^4, and +/-10^9, and 64-bit: +/-46340^4, and +/-10^17.
See builtins/VM/pPower for the precise details.
Added a note to phix.chm/core/atom/floats are not exact which explains
some of the reasons for needing/wanting to do this (on 64 bit).
(Specifically, rc/truncateable primes was broken on 64-bit)
This change also fixed several problems in t28prntf.e (on 64 bit).
07/06/2017: Bugfix: Crash in pilx86.e/opFor2. Change may be suspect.
Running an entirely incomplete source along the lines of:
for i=1 to length(board) do
if board[i]='1' then
?i
for j=1 to 0/*[=length(moves)]*/ do
if 0 then
end if
end for
end if
end for
The above crash occurred. Temporarily changing the ?9/0 to ?"9/0" and
running it caused all 1..50 to be printed, instead of the 14 expected.
Changed the offending code, inside the branch clearly commented with
"-- (we've deduced loop will iterate 0 times)", from:
if s5[pc]=opLabel then
if s5[pc+1]!=exitMerge then ?9/0 end if -- more investigation rqd?
pc += 4
end if
to
if s5[pc]=opLabel
and s5[pc+1]=exitMerge then
pc += 4
end if
Hopefully it is just the case that optimising away an entire for loop
has never happened in such close proximity to end if(s) before...
All tests pass with this change, but it is a "quick fix" that may need
to be revisited.
20/06/2017: You can now also declare variables as part of multiple assignment, eg
{string name, integer id} = lookup()
As well as being a generally useful enhancement/feature to have, this
also brings the language more in line with how I want to document it.
Note however sub-types do /NOT/ propagate as you might expect, eg:
{a, string b, c} = lookup()
will terminate in error if b already exists, or if a /or c/
does not already exist. While string {a, b, c} propagates
the type, and declares three new variables of type string,
that does /not/ happen for types inside the {}, except when
the type immediately precedes an opening (/nested) '{'.
Admittedly this is a simple practical choice/implementation
detail (see pmain.e/GetMultiAssignSet()) that it may be
possible to improve upon, but there are four use cases for
that routine, hence the simplest possible solution won.
02/09/2017 Bugfix: sprintf("%f",-9.999999999) yielded ".0" because round()
was not accounting for a leading '-'. (Amazingly, not seen b4)
25/09/2017 BUGFIX: ?sort({{0},{-3.8}}) gave completely the wrong results.
In compare({a},{b}) the nested compare of a,b was not handling
integers vs floats correctly; if {a,b} was {int,float} or
{float,int} it would simply assume int<float. The same bug was
present for infix <, <=, >, >=, though = and != were fine.
Quite amazing how that one lain undetected for 4..10 years!
Also, a=compare(a,b) looked dodgy - deallocating tgt before
the comparison - now does it after (no new tests though).
25/10/2017 An "illegal/unsupported construct" error now occurs if an end
for statement is immediately preceded by an unconditional exit.
Where possible, use a simple if construct instead. This proved
necessary because the opEndFor was being skipped, but that sets
the zero iterations jump. Example:
for i=1 to length(s) do
?s[i]
-- if 1 then -- (or constant DEBUG etc)
exit
-- end if
end for
(s[1] errored on length(s)=0, because the <1 jump was wrong.)
Note the /*unconditional*/ inner "if" makes no difference here.
However and of course, this sort of thing is (still) fine:
for i=1 to length(s) do
?s[i]
if "abc"="def" then
?"what??"
else
exit
end if
end for
(assuming the compiler does not optimise that test away too)
Update: Problem resurfaced. There are now fixes for this in
both pmain.e/DoFor() and pilx86.e/jskip().
29/10/2017 Bugfix. A call_func that triggered a type check was displaying
an incorrect return address/line number of -1. As part of this
fix, the ex.err no longer contains the stack entry arising from
pcallfunc.e/call_common(), somewhat unintended, but perhaps not
a bad thing. [Critical addition: !cf_ret now in the optable.]
01/11/2017 Bugfix. Multiple assignment style declarations were not always
correctly declaring/defining local variables, eg:
string str = "1"
procedure test()
-- this /should/ declare a new private variable,
string {str} = {"22"}
-- whereas this we /would/ expect to do damage!
-- {str} = {"22"}
if str="33" then ?9/0 end if --(suppress warning)
end procedure
test()
if length(str)=2 then ?9/0 end if
Previously, because there already was a variable named str,
it did not declare a new, and private, one inside test() -
but now it always does. Trivial change, that took far longer
to find then test and then write this, than actually code.
Version 0.7.2
=============
02/01/2017: Fixed one of the rarer and more confusing errors: if b.exw was
constant PINF = 1E308*1000
include m.e
and m.e was:
global constant PINF = 1E308*1000,
MINF = - PINF
Then we had an error in m.e of PINF not defined! The problem was
that DoConstant() was spotting the need to link together on the
S_Clink chain, but was doing so using an old copy of symtab[O],
from before the addSymEntryAt(), thereby messing up the S_Nlink
chain. It now fetches a fresh copy of symtab[O] -- simples.
03/01/2017: Finally added trace(3). However, it has exposed a glitch in the
file i/o routines: a missing line every 106/107 lines, which is
approx 7738/7811, suspiciously close to 8192-6*73(=7754) buffer
limits in VM/pfileioN.e - which will hopefully be trivial to
fix once better reproduced. [DEV/challenge]
05/01/2017: Bugfix: Unary minus incorrectly applied to routine_ids, eg:
constant r_x = routine_id("x")
?{r_x,-r_x,routine_id("x"),-routine_id("x")}
prints say {947,-947,947,-1755}. The problem was Factor() not
testing for K_rtn properly, it now does a proper opUminus.
[There is also a PushFactor(k,1,T_integer) after resolveRoutineId
that I suspect should really set isLiteral to 0, as another way
to solve the same problem, but that broke "p -test" badly... At
least, I think that is why -r_x works but the longer does not.]
Should only have been an issue compiling, not interpreting.
15/01/2017: Bugfix: fatal error in lineinfo() when trying to update LineTab
for "procedure text_mode() end procedure" (no \n). Similar fix
to that of 07/12/2015 for a completely empty source file.
23/01/2017: Bugfix: running IDE.exw crashed in Or_K_ridt() when calling
routine_id("x") mid-procedure x(with >=2 params). At that stage,
the S_Slink chain is "backwards" so must be scanned differently.
Version 0.7.1
=============
17/11/2016 You can now use platform(), machine_bits(), and machine_word() as
parameter defaults (optimised to literal integers in pmain.e/
getOneDefault). Also, a switch with no case statements now triggers
an error (because pilx86.e cannot cope, and besides it is bit like
having an if/elsif/else/end if with no if, no elsif, and maybe no
else). New builtins to_integer() and to_number(). Files are now
properly flushed/closed when an app terminates. Several x64 asm
fixes (far too many to list, though many were just minor glitches
in the list.asm files). Discovered rand() was really pants on x64,
rax is now initialised with seed<<32|seed, iyswim. puts1.e was
mutely displaying nothing, so it now does an AllocConsole first.
Version 0.7.0
=============
30/05/2016 Added bool as a simple alias of integer. It was about time.
(one line change to psym.e, plus syntax colour and help link.)
11/06/2016 BUGFIX: the break statement was only being permitted at the
"top level" inside DoSwitch(). Added DoBreak/breakBP/breakMerge
modelled after DoExit/exitBP/exitMerge. Took about 30 mins.
19/06/2016 Added "forward call assumed" warnings to Phix. Initially I was a
bit hesitant, but now that it is in place... it's a good thing.
Part of me is certain that some people will think it is a crime
against humanity that to get rid of the warnings you have to add
an explicit forward declaration, but... tough. Well, if it really
bothers you that much, change FWARN in p.exw to 0 and rebuild.
There already was a warning, been there for quite some time now,
when an implicit local got resolved to a global, which has not
caused me any trouble at all, in fact quite the opposite.
(In case you haven't guessed, it is very difficult for me to
properly justify any of this beyond a simple gut feeling.)
When you get a warning, and it is not something that would just
obviously be better off earlier on anyway, simply add an explicit
forward routine definition.
The only mention of (explicit) forward declarations in the manual
is in Core/Declarations/Scope. [DEV: updates to manual still rqd]
23/06/2016: Removed unused parameter warnings for routines which are the target
of routine_id (as long as that is known at compile-time). Callbacks
for win32lib etc demand a fixed set of parameters which got a bit
too much in one of the demos I had a play with. At the same time,
constants which are assigned the result of a function with side
effects other than E_none or E_other are also exhonorated from
unused warnings, such as constant TextLabel = create(Label,...).
[E_other stems, I believe, from the 09/02/2016 bugfix. It replaces
E-none in any routine of said that has any #ilASM in it.]
Version 0.6.7
=============
15/08/2015 Got the parlour trick ("p p p p p p p p -cp") all working again.