lape
lape copied to clipboard
Questions
@nielsAD Okay, I found my memory leak - was in the new namespaces code I added. As I am migrating code, I have a couple questions -
what do these do? autoproperties constaddress coperators
something I touched has broken accessing AnsiString[index], this was working until I started synchronizing lpcompiler lso options - which makes no sense to me: ERROR: Cannot invoke identifier at line 81, column 11 in file "tests/Arithmetics_String.lap
- I do like what you did for AddDefines() - NICE! Once I know these changes all work, I will sync back to my fork.
const
_a:string='abc';
var
a:string;
begin
a:=_a;
writeln(a);
writeln(length(a));
writeln(_a);
writeln(_a[1]);
writeln(a[1]);
end.
last writeln fails - where should I look?
@nielsAD Cannot invoke identifier at line 13, column 13 in file "t.p"
Once I have a ballpark of where to look, I can diff the source. oddly, my old code runs it perfectly, so this is where something I used to do, does not marry-up with the way it should be done now.
See tests for (1) autoproperties, (2) constaddress (allows pointers to constants), (3) compound operators.
As for the index operation; probably the result type is lost somewhere.
The code you pasted above works for me (RangeChecking is turned on by default). Maybe check if you made any modifications to handling lcoRangeCheck
.
works:
{$R-}
const
_a:string='abc';
var
a:string;
begin
a:=_a;
writeln(a);
writeln(length(a));
writeln(_a);
writeln(_a[1]);
writeln(a[1]);
end.
however, what if I need to turn off range checking for one routine and then back on for another? In my tests, I see compiler options are global not local to the routines. e.g. the last state of $R is the state used for the whole run-time. Is this fixable?
@nielsAD MP-Lape is now manually synchronized all .pas files.
To-Do:
- I am working on line by line tester for lpparser/lpcompiler script.
- I still have to move some code around to make LAPE mutli-threaded friendly for my socket server. (e.g. lpparser:
initialization
Lape_InitKeywordsCache();
{$IFDEF LoadDefaultFormatSettings}
GetLocaleFormatSettings(0, FormatSettings);
{$ENDIF}
finalization
Lape_ClearKeywordsCache();
making it thread safe). 3. then synchronizing all my docs to your docs/lape.rst file ;-)
however, what if I need to turn off range checking for one routine and then back on for another? In my tests, I see compiler options are global not local to the routines. e.g. the last state of $R is the state used for the whole run-time. Is this fixable? - 3FLLC
The switch does not affect the whole script but only from the point where it's toggled, and until it's changed again, switches are parsed as we go.
This should display it:
var
a:array of Int32;
begin
{$R-}
a[10]; //passes by
{$R+}
try
a[10]; //raises
except
WriteLn 'raised';
end;
{$R-} //the rest of the code uses R- now.
a[10]; //passes by
end.
so for your function, you enable it in the begining, and then disable it at the end.
Your are right, I introduced the bug :-(
fixing property Options:{...} read FOptions write FBaseOptions; (making it use SetOptions) ended breaking FOptions' scope. Undoing my "fix" and just applying "Compiler.Reset()" everywhere I need the change to happen pre Compiler.compile(...).
Thanks!!
Undid my setOptions() change to lpvartypes (compiler base), and I still get:
Compilation error: "Cannot invoke identifier at line 13, column 6
- not RUNTIME compile time... but when I compile w/o my changes your code example works... so I am still digging in... thanks!
@WarPie - thanks for proven it did work - after doing a line by line comparison - I finally found, _RangeCheck was my issue. It was not migrated into MP2, as I thought it was like Between(..) or inRange(...) from my Math RTL. Once I found vartypes_array uses _RangeCheck I was able to resolve it. PHEW!
@nielsAD new question - I am porting over some UUID/MSGID code from C to MP.... how hard would it be for us to implement "bit" support in records?
struct
{
unsigned TaskNumber:5;
unsigned DayOfYear:9;
unsigned Year:2; /* Enough to meet the three-year rule */
unsigned Secs30:12;
unsigned Count:4;
} x; // sizeof() == 32
Or is there a way to have LA-PE align to this structure?
The best way to work around this is by just using a 32 bit integer type and wrapping the C fields into getters/setters.
Adding this to Lape is possible but difficult, because there's nothing like it at the moment. Currently, there's no read
evaluation, which would be needed for something like this. Adding that is non-trivial, but would also be beneficial for properties.
@nielsAD a while back you helped me implement this, but I cannot find my notes.
Write(#27+']2;LiveMenu - Telnet Edition'+#7);
ctlcms.init(nil);
ctlcms.setFilename(rootpath+'control.cms');
ctlcms.setFirstlineIsSchema(false);
ctlcms.open();
ds:=ctlcms;
df:=ds.FieldByName('Field1');
_Version:=df.getAsFloat;
ctlcms.free;
Note I have to store TField to DF then I can work with DF.getAsFloat. You had pointed me to the piece of code to understand ds.FieldByName("Field1").getAsFloat --- right now if I run that statement I get "Variable expected at line..." so I have to store the object to variable, then reference that variable/object to get to it's methods. ... do you recall what I need to expand out?? (I still have my pre-LAPE-MERGE code, so I will be able to cut-n-paste my patch, hopefully).
You might have to work with constref
or static
keywords as in tests/Method_OfType.lap
.
Actually last time, you had me work with the internal routine that handled "dot", I just don't remember it's name to go back and find how I fixed it.
@nielsAD could we support code like:
{$DEFINE BURGER}
{$IFDEF HOTDOG OR BURGER}
!Error
{$ENDIF}
I am porting a lot of C code over, and I run into code like: #if defined(WITH_ZLIB) || defined(WITH_BZLIB2) and I don't want to write the {$IFDEF} code twice, nor write:
{$IFDEF WITH_ZLIB}
{$IFDEF WITH_BZLIB2}
{$DEFINE WITH_ZLIB_BZLIB2}
etc. The goal is to keep the code as close to original as possible. But, I am not sure what it would take to add an evaluation for the IFnDEF logic parser.
I'm not sure what we discussed last time regarding fields. You might be able to find it in a mail?
$IF
conditionals shouldn't be that difficult to add, as you can reuse the expression parser and constant evaluation parts. Adding declared
and defined
functions would be a bit more difficult.
@nielsAD what is the correct way to write this in a LAPE script?
type
TDateTimeRec = record
case TFieldType of
ftDate: (
Date: LongInt;
);
ftTime: (
Time: LongInt;
);
ftDateTime: (
DateTime: Double;
);
end;
Is that where I would use a Union? And once coded, how would I access each element?
Thanks again! Ozz
Yes, that should be turned into a union.
type
TDateTimeRec = union
Date: LongInt;
Time: LongInt;
DateTime: Double;
end;
var
dt: TDateTimeRec;
begin
dt.Date := 1;
WriteLn(dt);
end;
Darn, error:
type TDateTimeRec = union Date: LongInt; Time: LongInt; DateTime: Double; end;
var dt: TDateTimeRec; begin dt.Date := 40000; dt.Time := 400; WriteLn(dt); end;
produces: {DATE = 400, TIME = 400, DATETIME = 1.97626258336499E-321}
Looks like union is expecting a single element period… does not understand the grouping of the bytes. Flipping them around JIC still same result: {DATETIME = 1.97626258336499E-321, DATE = 400, TIME = 400}
:-(
On Feb 22, 2017, at 10:07 AM, Niels AD [email protected] wrote:
Yes, that should be turned into a union.
type TDateTimeRec = union Date: LongInt; Time: LongInt; DateTime: Double; end;
var dt: TDateTimeRec; begin dt.Date := 1; WriteLn(dt); end; — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/nielsAD/lape/issues/86#issuecomment-281695449, or mute the thread https://github.com/notifications/unsubscribe-auth/AMlpMstYT4ps4ZcLEVgFBbJD5wf0hrYeks5rfE8igaJpZM4JP-9k.
I get the same result when running this with FreePascal... I'm not sure what you're expecting here?
union = 8 bytes in memory long = bytes 1 2 3 4 long = bytes 5 6 7 8 double = bytes 1..8
?
On Feb 22, 2017, at 11:50 AM, Niels AD [email protected] wrote:
I get the same result when running this with FreePascal... I'm not sure what you're expecting here?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/nielsAD/lape/issues/86#issuecomment-281728557, or mute the thread https://github.com/notifications/unsubscribe-auth/AMlpMohCkzd_Qmml93d95A9DQcV0evZEks5rfGdIgaJpZM4JP-9k.
Use a nested record:
type
TDateTimeRec = union
dt: record
Date: LongInt;
Time: LongInt;
end;
DateTime: Double;
end;
var
rec: TDateTimeRec;
begin
rec.dt := [123, 456];
WriteLn(rec);
end;
Thank you !! That is exactly what I was trying to port over… the pascal code was a record with a case inside it.. I will add this to my notes.
On Feb 22, 2017, at 12:03 PM, Niels AD [email protected] wrote:
Use a nested record:
type TDateTimeRec = union dt: record Date: LongInt; Time: LongInt; end; DateTime: Double; end;
var rec: TDateTimeRec; begin rec.dt := [123, 456]; WriteLn(rec); end; — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/nielsAD/lape/issues/86#issuecomment-281732659, or mute the thread https://github.com/notifications/unsubscribe-auth/AMlpMnx63TokdxUSmmtbkT3AZvip_fyYks5rfGpQgaJpZM4JP-9k.
@nielsAD
I am reviewing Turbo Pascal 7 manual, and came across this - where would be the "correct" place for me to implement this support:
(. .) "A left bracket ([) is equivalent to the character pair of left parenthesis and a period-(., and a right bracket (]) is equivalent to the character pair of a period and a right parenthesis-.)."
You can add this in lpparser.pas
. Just have the parser return it as if it was a regular bracket.
@nielsAD
Hope all is well... is there a way to mimic OnShutdown, or ExitProc. http://putka.upm.si/langref/turboPascal/0681.html
When debugging a script that is running as an Apache Module, I would like to inject some code which documents which function, line, etc. was last running when the error occurred. And if possible, if FileHandle is Open, Close it - as sometimes the error is when I am saving to my log the web variables... without the close, it does not always write the last bit of text.
Ozz
A try
..finally
around your main function should work.
I tried, does not - it has to be something out in lpCompiler/lpInterpreter layer. As I need a way to PUSH into the AST code, Terminate - and it jump to the terminate code. When Apache says kill thread, I can trap the signal, however, the .run() is terminated. So, I was hoping for another way of letting the AST code "hey call this" that I could manually push. I have modified my run() that exception handling is shared with the script and the host - so I can always document the exception if from the script layer. However, sometimes the client disappears (hackers for example) before the script runs, and Apache signals me to abort right now.
If we can figure away to allow the host to do this, it may be useful when implementing a GUI/event driven wrapper... like handling windows events. I
@nielsAD the following code gives me Runtime error: "Invalid jump". Besides not know why, I would like to expand the error to explain what caused the invalid jump.
`uses Math;
const MaxProbability=1000;
type LootType=(Bloodstone, Copper, Emeraldite, Gold, Heronite, Platinum, Shadownite, Silver, Soranite, Umbrarite, Cobalt, Iron, Default); Looter = Class Probabilites:Array[0..12] of Longint; Choose:private function:LootType of object; AsString:private function(l:LootType):String of object; End;
function Looter.Choose:LootType; var Loop,randomValue:Word;
Begin randomValue:=Random(MaxProbability-1); Loop:=0; While Probabilites[Loop mod 12]<randomValue do begin Inc(Loop); End; Result:=LootType(Loop mod 12); End;
function Looter.AsString(l:LootType):String; Begin Case l of LootType(Bloodstone):Result:='Bloodstone'; LootType(Copper):Result:='Copper'; LootType(Emeraldite):Result:='Emeraldite'; LootType(Gold):Result:='Gold'; LootType(Heronite):Result:='Heronite'; LootType(Platinum):Result:='Platinum'; LootType(Shadownite):Result:='Shadownite'; LootType(Silver):Result:='Silver'; LootType(Soranite):Result:='Soranite'; LootType(Umbrarite):Result:='Umbrarite'; LootType(Cobalt):Result:='Cobalt'; LootType(Iron):Result:='Iron'; Else Result:='Iron'; End; End;
procedure Looter.Free; Begin End;
// Must be listed after all actual definitions // procedure Looter.Init; Begin Randomize; with Self do begin Probabilites[0]:=10; Probabilites[1]:=77; Probabilites[2]:=105; Probabilites[3]:=125; Probabilites[4]:=142; Probabilites[5]:=159; Probabilites[6]:=172; Probabilites[7]:=200; Probabilites[8]:=201; Probabilites[9]:=202; Probabilites[10]:=216; Probabilites[11]:=282; Probabilites[12]:=MaxProbability; TMethod(@Choose) := [@Looter.Choose, @Self]; TMethod(@Free) := [@Looter.Free, @Self]; End; End;
var loot:looter; n:longint;
begin loot.init; for n:=0 to 99 do Writeln(Loot.AsString(Loot.choose)); loot.free; end.`
@nielsAD
Finally found the Enum and Set issue - problem is lpvartypes_ord.pas ToString for Enum is using System.SizeInt, System.String, etc ... in my version - System is not defined yet... as I had started implementing NameSpace support (and never finished). Removed "System." in the few places you reference it - and viola, I can writeln Sets and Enumerations without issue.
This fix also allows that last game post to work when changing to Writeln(Loot.Choose);
- Not sure why calling AsString(Choose) produces "Invalid Jump"....
Regards, Ozz