raw
ffa_ch4_ffacalc.kv      1 ------------------------------------------------------------------------------
ffa_ch4_ffacalc.kv 2 ------------------------------------------------------------------------------
ffa_ch4_ffacalc.kv 3 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. --
ffa_ch4_ffacalc.kv 4 -- --
ffa_ch4_ffacalc.kv 5 -- (C) 2017 Stanislav Datskovskiy ( www.loper-os.org ) --
ffa_ch4_ffacalc.kv 6 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html --
ffa_ch4_ffacalc.kv 7 -- --
ffa_ch4_ffacalc.kv 8 -- You do not have, nor can you ever acquire the right to use, copy or --
ffa_ch4_ffacalc.kv 9 -- distribute this software ; Should you use this software for any purpose, --
ffa_ch4_ffacalc.kv 10 -- or copy and distribute it to anyone or in any manner, you are breaking --
ffa_ch4_ffacalc.kv 11 -- the laws of whatever soi-disant jurisdiction, and you promise to --
ffa_ch4_ffacalc.kv 12 -- continue doing so for the indefinite future. In any case, please --
ffa_ch4_ffacalc.kv 13 -- always : read and understand any software ; verify any PGP signatures --
ffa_ch4_ffacalc.kv 14 -- that you use - for any purpose. --
ffa_ch4_ffacalc.kv 15 -- --
ffa_ch4_ffacalc.kv 16 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . --
ffa_ch4_ffacalc.kv 17 ------------------------------------------------------------------------------
ffa_ch4_ffacalc.kv 18 ------------------------------------------------------------------------------
ffa_ch4_ffacalc.kv 19
ffa_ch4_ffacalc.kv 20 -- Basics
ffa_ch8_randomism.kv 21 with OS; use OS;
ffa_ch8_randomism.kv 22 with CmdLine; use CmdLine;
ffa_ch4_ffacalc.kv 23
ffa_ch4_ffacalc.kv 24 -- FFA
ffa_ch11_tuning_a... 25 with FFA; use FFA;
ffa_ch4_ffacalc.kv 26
ffa_ch11_tuning_a... 27 -- For the intrinsic equality operator on Words
ffa_ch11_tuning_a... 28 use type FFA.Word;
ffa_ch4_ffacalc.kv 29
ffa_ch8_randomism.kv 30 -- For RNG:
ffa_ch8_randomism.kv 31 with FFA_RNG; use FFA_RNG;
ffa_ch8_randomism.kv 32
ffa_ch8_randomism.kv 33
ffa_ch4_ffacalc.kv 34 procedure FFA_Calc is
ffa_ch4_ffacalc.kv 35
ffa_ch8_randomism.kv 36 Width : Positive; -- Desired FFA Width
ffa_ch8_randomism.kv 37 Height : Positive; -- Desired Height of Stack
ffa_ch8_randomism.kv 38 RNG : RNG_Device; -- The active RNG device.
ffa_ch4_ffacalc.kv 39
ffa_ch4_ffacalc.kv 40 begin
ffa_ch8_randomism.kv 41 if Arg_Count < 3 or Arg_Count > 4 then
ffa_ch8_randomism.kv 42 Eggog("Usage: ./ffa_calc WIDTH HEIGHT [/dev/rng]");
ffa_ch4_ffacalc.kv 43 end if;
ffa_ch4_ffacalc.kv 44
ffa_ch4_ffacalc.kv 45 declare
ffa_ch4_ffacalc.kv 46 Arg1 : CmdLineArg;
ffa_ch4_ffacalc.kv 47 Arg2 : CmdLineArg;
ffa_ch4_ffacalc.kv 48 begin
ffa_ch4_ffacalc.kv 49 -- Get commandline args:
ffa_ch4_ffacalc.kv 50 Get_Argument(1, Arg1); -- First arg
ffa_ch4_ffacalc.kv 51 Get_Argument(2, Arg2); -- Second arg
ffa_ch4_ffacalc.kv 52
ffa_ch8_randomism.kv 53 if Arg_Count = 4 then
ffa_ch8_randomism.kv 54 -- RNG was specified:
ffa_ch8_randomism.kv 55 declare
ffa_ch8_randomism.kv 56 Arg3 : CmdLineArg;
ffa_ch8_randomism.kv 57 begin
ffa_ch8_randomism.kv 58 Get_Argument(3, Arg3); -- Third arg (optional)
ffa_ch8_randomism.kv 59
ffa_ch8_randomism.kv 60 -- Ada.Sequential_IO chokes on paths with trailing whitespace!
ffa_ch8_randomism.kv 61 -- So we have to give it a trimmed path. But we can't use
ffa_ch8_randomism.kv 62 -- Ada.Strings.Fixed.Trim, because it suffers from
ffa_ch8_randomism.kv 63 -- SecondaryStackism-syphilis. Instead we are stuck doing this:
ffa_ch8_randomism.kv 64 Init_RNG(RNG, Arg3(Arg3'First .. Len_Arg(3)));
ffa_ch8_randomism.kv 65 end;
ffa_ch8_randomism.kv 66 else
ffa_ch8_randomism.kv 67 -- RNG was NOT specified:
ffa_ch8_randomism.kv 68 Init_RNG(RNG); -- Use the machine default then
ffa_ch8_randomism.kv 69 end if;
ffa_ch8_randomism.kv 70
ffa_ch4_ffacalc.kv 71 -- Parse into Positives:
ffa_ch4_ffacalc.kv 72 Width := Positive'Value(Arg1);
ffa_ch4_ffacalc.kv 73 Height := Positive'Value(Arg2);
ffa_ch4_ffacalc.kv 74 exception
ffa_ch4_ffacalc.kv 75 when others =>
ffa_ch4_ffacalc.kv 76 Eggog("Invalid arguments!");
ffa_ch4_ffacalc.kv 77 end;
ffa_ch4_ffacalc.kv 78
ffa_ch4_ffacalc.kv 79 -- Test if proposed Width is permissible:
ffa_ch11_tuning_a... 80 if not FFA_FZ_Valid_Bitness_P(Width) then
ffa_ch11_tuning_a... 81 Eggog("Invalid Width: " & FFA_Validity_Rule_Doc);
ffa_ch4_ffacalc.kv 82 end if;
ffa_ch4_ffacalc.kv 83
ffa_ch4_ffacalc.kv 84 -- The Calculator itself:
ffa_ch4_ffacalc.kv 85 declare
ffa_ch4_ffacalc.kv 86
ffa_ch4_ffacalc.kv 87 -- The number of Words required to make a FZ of the given Bitness.
ffa_ch4_ffacalc.kv 88 Wordness : Indices := Indices(Width / Bitness);
ffa_ch4_ffacalc.kv 89
ffa_ch4_ffacalc.kv 90 --------------------------------------------------------
ffa_ch4_ffacalc.kv 91 -- State --
ffa_ch4_ffacalc.kv 92 --------------------------------------------------------
ffa_ch4_ffacalc.kv 93 -- The Stack:
ffa_ch4_ffacalc.kv 94 subtype Stack_Positions is Natural range 0 .. Height;
ffa_ch4_ffacalc.kv 95 type Stacks is array(Stack_Positions range <>) of FZ(1 .. Wordness);
ffa_ch4_ffacalc.kv 96 Stack : Stacks(Stack_Positions'Range);
ffa_ch4_ffacalc.kv 97
ffa_ch4_ffacalc.kv 98 -- Stack Pointer:
ffa_ch4_ffacalc.kv 99 SP : Stack_Positions := Stack_Positions'First;
ffa_ch4_ffacalc.kv 100
ffa_ch4_ffacalc.kv 101 -- Carry/Borrow Flag:
ffa_ch4_ffacalc.kv 102 Flag : WBool := 0;
ffa_ch4_ffacalc.kv 103
ffa_ch4_ffacalc.kv 104 -- Odometer:
ffa_ch4_ffacalc.kv 105 Pos : Natural := 0;
ffa_ch4_ffacalc.kv 106
ffa_ch4_ffacalc.kv 107 -- The current levels of the three types of nestedness:
ffa_ch4_ffacalc.kv 108 QuoteLevel : Natural := 0;
ffa_ch4_ffacalc.kv 109 CommLevel : Natural := 0;
ffa_ch4_ffacalc.kv 110 CondLevel : Natural := 0;
ffa_ch13_measure_... 111
ffa_ch13_measure_... 112 -- Prefixed Operators
ffa_ch13_measure_... 113 PrevC : Character := ' ';
ffa_ch13_measure_... 114 HavePrefix : Boolean := False;
ffa_ch13_measure_... 115
ffa_ch4_ffacalc.kv 116 --------------------------------------------------------
ffa_ch4_ffacalc.kv 117
ffa_ch4_ffacalc.kv 118
ffa_ch4_ffacalc.kv 119 -- Clear the stack and set SP to bottom.
ffa_ch4_ffacalc.kv 120 procedure Zap is
ffa_ch4_ffacalc.kv 121 begin
ffa_ch4_ffacalc.kv 122 -- Clear the stack
ffa_ch4_ffacalc.kv 123 for i in Stack'Range loop
ffa_ch11_tuning_a... 124 FFA_FZ_Clear(Stack(i));
ffa_ch4_ffacalc.kv 125 end loop;
ffa_ch4_ffacalc.kv 126 -- Set SP to bottom
ffa_ch4_ffacalc.kv 127 SP := Stack_Positions'First;
ffa_ch4_ffacalc.kv 128 -- Clear Overflow flag
ffa_ch4_ffacalc.kv 129 Flag := 0;
ffa_ch13_measure_... 130 -- Clear prefix
ffa_ch13_measure_... 131 HavePrefix := False;
ffa_ch13_measure_... 132 PrevC := ' ';
ffa_ch4_ffacalc.kv 133 end Zap;
ffa_ch4_ffacalc.kv 134
ffa_ch4_ffacalc.kv 135
ffa_ch4_ffacalc.kv 136 -- Report a fatal error condition at the current symbol
ffa_ch4_ffacalc.kv 137 procedure E(S : in String) is
ffa_ch4_ffacalc.kv 138 begin
ffa_ch4_ffacalc.kv 139 Eggog("Pos:" & Natural'Image(Pos) & ": " & S);
ffa_ch4_ffacalc.kv 140 end E;
ffa_ch4_ffacalc.kv 141
ffa_ch4_ffacalc.kv 142
ffa_ch4_ffacalc.kv 143 -- Move SP up
ffa_ch4_ffacalc.kv 144 procedure Push is
ffa_ch4_ffacalc.kv 145 begin
ffa_ch4_ffacalc.kv 146 if SP = Stack_Positions'Last then
ffa_ch4_ffacalc.kv 147 E("Stack Overflow!");
ffa_ch4_ffacalc.kv 148 else
ffa_ch4_ffacalc.kv 149 SP := SP + 1;
ffa_ch4_ffacalc.kv 150 end if;
ffa_ch4_ffacalc.kv 151 end Push;
ffa_ch4_ffacalc.kv 152
ffa_ch4_ffacalc.kv 153
ffa_ch4_ffacalc.kv 154 -- Discard the top of the stack
ffa_ch4_ffacalc.kv 155 procedure Drop is
ffa_ch4_ffacalc.kv 156 begin
ffa_ch11_tuning_a... 157 FFA_FZ_Clear(Stack(SP));
ffa_ch4_ffacalc.kv 158 SP := SP - 1;
ffa_ch4_ffacalc.kv 159 end Drop;
ffa_ch4_ffacalc.kv 160
ffa_ch4_ffacalc.kv 161
ffa_ch4_ffacalc.kv 162 -- Check if stack has the necessary N items
ffa_ch4_ffacalc.kv 163 procedure Want(N : in Positive) is
ffa_ch4_ffacalc.kv 164 begin
ffa_ch4_ffacalc.kv 165 if SP < N then
ffa_ch4_ffacalc.kv 166 E("Stack Underflow!");
ffa_ch4_ffacalc.kv 167 end if;
ffa_ch4_ffacalc.kv 168 end Want;
ffa_ch4_ffacalc.kv 169
ffa_ch4_ffacalc.kv 170
ffa_ch5_egypt.kv 171 -- Ensure that a divisor is not zero
ffa_ch5_egypt.kv 172 procedure MustNotZero(D : in FZ) is
ffa_ch5_egypt.kv 173 begin
ffa_ch11_tuning_a... 174 if FFA_FZ_ZeroP(D) = 1 then
ffa_ch5_egypt.kv 175 E("Division by Zero!");
ffa_ch5_egypt.kv 176 end if;
ffa_ch5_egypt.kv 177 end MustNotZero;
ffa_ch5_egypt.kv 178
ffa_ch5_egypt.kv 179
ffa_ch4_ffacalc.kv 180 -- Slide a new hex digit into the FZ on top of stack
ffa_ch11_tuning_a... 181 procedure Ins_Hex_Digit(Digit : in Nibble) is
ffa_ch11_tuning_a... 182 Overflow : WBool := 0;
ffa_ch4_ffacalc.kv 183 begin
ffa_ch11_tuning_a... 184
ffa_ch11_tuning_a... 185 -- Insert the given nibble, and detect any overflow:
ffa_ch11_tuning_a... 186 FFA_FZ_Insert_Bottom_Nibble(N => Stack(SP),
ffa_ch11_tuning_a... 187 D => Digit,
ffa_ch11_tuning_a... 188 Overflow => Overflow);
ffa_ch4_ffacalc.kv 189
ffa_ch4_ffacalc.kv 190 -- Constants which exceed the Width are forbidden:
ffa_ch11_tuning_a... 191 if Overflow = 1 then
ffa_ch4_ffacalc.kv 192 E("Constant Exceeds Bitness!");
ffa_ch4_ffacalc.kv 193 end if;
ffa_ch4_ffacalc.kv 194
ffa_ch4_ffacalc.kv 195 end;
ffa_ch4_ffacalc.kv 196
ffa_ch4_ffacalc.kv 197
ffa_ch11_tuning_a... 198 -- Emit an ASCII representation of N to the terminal
ffa_ch11_tuning_a... 199 procedure Print_FZ(N : in FZ) is
ffa_ch11_tuning_a... 200 S : String(1 .. FFA_FZ_ASCII_Length(N)); -- Mandatorily, exact size
ffa_ch11_tuning_a... 201 begin
ffa_ch11_tuning_a... 202 FFA_FZ_To_Hex_String(N, S); -- Convert N to ASCII hex
ffa_ch11_tuning_a... 203 Write_String(S); -- Print the result to stdout
ffa_ch11_tuning_a... 204 Write_Newline; -- Print newline, for clarity.
ffa_ch11_tuning_a... 205 end Print_FZ;
ffa_ch11_tuning_a... 206
ffa_ch11_tuning_a... 207
ffa_ch13_measure_... 208 -- Denote that the given op is a prefix
ffa_ch13_measure_... 209 procedure IsPrefix is
ffa_ch13_measure_... 210 begin
ffa_ch13_measure_... 211 HavePrefix := True;
ffa_ch13_measure_... 212 end IsPrefix;
ffa_ch13_measure_... 213
ffa_ch13_measure_... 214
ffa_ch4_ffacalc.kv 215 -- Execute a Normal Op
ffa_ch4_ffacalc.kv 216 procedure Op_Normal(C : in Character) is
ffa_ch4_ffacalc.kv 217
ffa_ch4_ffacalc.kv 218 -- Over/underflow output from certain ops
ffa_ch4_ffacalc.kv 219 F : Word;
ffa_ch4_ffacalc.kv 220
ffa_ch4_ffacalc.kv 221 begin
ffa_ch4_ffacalc.kv 222
ffa_ch4_ffacalc.kv 223 case C is
ffa_ch4_ffacalc.kv 224
ffa_ch4_ffacalc.kv 225 --------------
ffa_ch4_ffacalc.kv 226 -- Stickies --
ffa_ch4_ffacalc.kv 227 --------------
ffa_ch4_ffacalc.kv 228 -- Enter Commented
ffa_ch4_ffacalc.kv 229 when '(' =>
ffa_ch4_ffacalc.kv 230 CommLevel := 1;
ffa_ch4_ffacalc.kv 231
ffa_ch4_ffacalc.kv 232 -- Exit Commented (but we aren't in it!)
ffa_ch4_ffacalc.kv 233 when ')' =>
ffa_ch4_ffacalc.kv 234 E("Mismatched close-comment parenthesis !");
ffa_ch4_ffacalc.kv 235
ffa_ch4_ffacalc.kv 236 -- Enter Quoted
ffa_ch4_ffacalc.kv 237 when '[' =>
ffa_ch4_ffacalc.kv 238 QuoteLevel := 1;
ffa_ch4_ffacalc.kv 239
ffa_ch4_ffacalc.kv 240 -- Exit Quoted (but we aren't in it!)
ffa_ch4_ffacalc.kv 241 when ']' =>
ffa_ch4_ffacalc.kv 242 E("Mismatched close-quote bracket !");
ffa_ch4_ffacalc.kv 243
ffa_ch4_ffacalc.kv 244 -- Enter a ~taken~ Conditional branch:
ffa_ch4_ffacalc.kv 245 when '{' =>
ffa_ch4_ffacalc.kv 246 Want(1);
ffa_ch11_tuning_a... 247 if FFA_FZ_ZeroP(Stack(SP)) = 1 then
ffa_ch4_ffacalc.kv 248 CondLevel := 1;
ffa_ch4_ffacalc.kv 249 end if;
ffa_ch4_ffacalc.kv 250 Drop;
ffa_ch4_ffacalc.kv 251
ffa_ch4_ffacalc.kv 252 -- Exit from a ~non-taken~ Conditional branch:
ffa_ch4_ffacalc.kv 253 -- ... we push a 0, to suppress the 'else' clause
ffa_ch4_ffacalc.kv 254 when '}' =>
ffa_ch4_ffacalc.kv 255 Push;
ffa_ch11_tuning_a... 256 FFA_WBool_To_FZ(0, Stack(SP));
ffa_ch4_ffacalc.kv 257
ffa_ch4_ffacalc.kv 258 ----------------
ffa_ch4_ffacalc.kv 259 -- Immediates --
ffa_ch4_ffacalc.kv 260 ----------------
ffa_ch4_ffacalc.kv 261
ffa_ch4_ffacalc.kv 262 -- These operate on the FZ ~currently~ at top of the stack;
ffa_ch4_ffacalc.kv 263 -- and this means that the stack may NOT be empty.
ffa_ch4_ffacalc.kv 264
ffa_ch4_ffacalc.kv 265 when '0' .. '9' =>
ffa_ch4_ffacalc.kv 266 Want(1);
ffa_ch11_tuning_a... 267 Ins_Hex_Digit(Character'Pos(C) - Character'Pos('0'));
ffa_ch4_ffacalc.kv 268
ffa_ch4_ffacalc.kv 269 when 'A' .. 'F' =>
ffa_ch4_ffacalc.kv 270 Want(1);
ffa_ch11_tuning_a... 271 Ins_Hex_Digit(10 + Character'Pos(C) - Character'Pos('A'));
ffa_ch4_ffacalc.kv 272
ffa_ch4_ffacalc.kv 273 when 'a' .. 'f' =>
ffa_ch4_ffacalc.kv 274 Want(1);
ffa_ch11_tuning_a... 275 Ins_Hex_Digit(10 + Character'Pos(C) - Character'Pos('a'));
ffa_ch4_ffacalc.kv 276
ffa_ch4_ffacalc.kv 277 ------------------
ffa_ch4_ffacalc.kv 278 -- Stack Motion --
ffa_ch4_ffacalc.kv 279 ------------------
ffa_ch4_ffacalc.kv 280
ffa_ch4_ffacalc.kv 281 -- Push a 0 onto the stack
ffa_ch4_ffacalc.kv 282 when '.' =>
ffa_ch4_ffacalc.kv 283 Push;
ffa_ch11_tuning_a... 284 FFA_FZ_Clear(Stack(SP));
ffa_ch4_ffacalc.kv 285
ffa_ch4_ffacalc.kv 286 -- Dup
ffa_ch4_ffacalc.kv 287 when '"' =>
ffa_ch4_ffacalc.kv 288 Want(1);
ffa_ch4_ffacalc.kv 289 Push;
ffa_ch4_ffacalc.kv 290 Stack(SP) := Stack(SP - 1);
ffa_ch4_ffacalc.kv 291
ffa_ch4_ffacalc.kv 292 -- Drop
ffa_ch4_ffacalc.kv 293 when '_' =>
ffa_ch4_ffacalc.kv 294 Want(1);
ffa_ch4_ffacalc.kv 295 Drop;
ffa_ch4_ffacalc.kv 296
ffa_ch4_ffacalc.kv 297 -- Swap
ffa_ch4_ffacalc.kv 298 when ''' =>
ffa_ch4_ffacalc.kv 299 Want(2);
ffa_ch11_tuning_a... 300 FFA_FZ_Swap(Stack(SP), Stack(SP - 1));
ffa_ch4_ffacalc.kv 301
ffa_ch4_ffacalc.kv 302 -- Over
ffa_ch4_ffacalc.kv 303 when '`' =>
ffa_ch4_ffacalc.kv 304 Want(2);
ffa_ch4_ffacalc.kv 305 Push;
ffa_ch4_ffacalc.kv 306 Stack(SP) := Stack(SP - 2);
ffa_ch4_ffacalc.kv 307
ffa_ch4_ffacalc.kv 308 ----------------
ffa_ch4_ffacalc.kv 309 -- Predicates --
ffa_ch4_ffacalc.kv 310 ----------------
ffa_ch4_ffacalc.kv 311
ffa_ch4_ffacalc.kv 312 -- Equality
ffa_ch4_ffacalc.kv 313 when '=' =>
ffa_ch4_ffacalc.kv 314 Want(2);
ffa_ch11_tuning_a... 315 FFA_WBool_To_FZ(FFA_FZ_EqP(X => Stack(SP),
ffa_ch11_tuning_a... 316 Y => Stack(SP - 1)),
ffa_ch11_tuning_a... 317 Stack(SP - 1));
ffa_ch4_ffacalc.kv 318 Drop;
ffa_ch4_ffacalc.kv 319
ffa_ch4_ffacalc.kv 320 -- Less-Than
ffa_ch4_ffacalc.kv 321 when '<' =>
ffa_ch4_ffacalc.kv 322 Want(2);
ffa_ch11_tuning_a... 323 FFA_WBool_To_FZ(FFA_FZ_LessThanP(X => Stack(SP - 1),
ffa_ch11_tuning_a... 324 Y => Stack(SP)),
ffa_ch11_tuning_a... 325 Stack(SP - 1));
ffa_ch4_ffacalc.kv 326 Drop;
ffa_ch4_ffacalc.kv 327
ffa_ch4_ffacalc.kv 328 -- Greater-Than
ffa_ch4_ffacalc.kv 329 when '>' =>
ffa_ch4_ffacalc.kv 330 Want(2);
ffa_ch11_tuning_a... 331 FFA_WBool_To_FZ(FFA_FZ_GreaterThanP(X => Stack(SP - 1),
ffa_ch11_tuning_a... 332 Y => Stack(SP)),
ffa_ch11_tuning_a... 333 Stack(SP - 1));
ffa_ch4_ffacalc.kv 334 Drop;
ffa_ch4_ffacalc.kv 335
ffa_ch4_ffacalc.kv 336 ----------------
ffa_ch4_ffacalc.kv 337 -- Arithmetic --
ffa_ch4_ffacalc.kv 338 ----------------
ffa_ch4_ffacalc.kv 339
ffa_ch4_ffacalc.kv 340 -- Subtract
ffa_ch4_ffacalc.kv 341 when '-' =>
ffa_ch4_ffacalc.kv 342 Want(2);
ffa_ch11_tuning_a... 343 FFA_FZ_Subtract(X => Stack(SP - 1),
ffa_ch11_tuning_a... 344 Y => Stack(SP),
ffa_ch11_tuning_a... 345 Difference => Stack(SP - 1),
ffa_ch11_tuning_a... 346 Underflow => F);
ffa_ch11_tuning_a... 347 Flag := FFA_Word_NZeroP(F);
ffa_ch4_ffacalc.kv 348 Drop;
ffa_ch4_ffacalc.kv 349
ffa_ch4_ffacalc.kv 350 -- Add
ffa_ch4_ffacalc.kv 351 when '+' =>
ffa_ch4_ffacalc.kv 352 Want(2);
ffa_ch11_tuning_a... 353 FFA_FZ_Add(X => Stack(SP - 1),
ffa_ch11_tuning_a... 354 Y => Stack(SP),
ffa_ch11_tuning_a... 355 Sum => Stack(SP - 1),
ffa_ch11_tuning_a... 356 Overflow => F);
ffa_ch11_tuning_a... 357 Flag := FFA_Word_NZeroP(F);
ffa_ch4_ffacalc.kv 358 Drop;
ffa_ch4_ffacalc.kv 359
ffa_ch5_egypt.kv 360 -- Divide and give Quotient and Remainder
ffa_ch5_egypt.kv 361 when '\' =>
ffa_ch5_egypt.kv 362 Want(2);
ffa_ch5_egypt.kv 363 MustNotZero(Stack(SP));
ffa_ch11_tuning_a... 364 FFA_FZ_IDiv(Dividend => Stack(SP - 1),
ffa_ch11_tuning_a... 365 Divisor => Stack(SP),
ffa_ch11_tuning_a... 366 Quotient => Stack(SP - 1),
ffa_ch11_tuning_a... 367 Remainder => Stack(SP));
ffa_ch5_egypt.kv 368
ffa_ch5_egypt.kv 369 -- Divide and give Quotient only
ffa_ch5_egypt.kv 370 when '/' =>
ffa_ch5_egypt.kv 371 Want(2);
ffa_ch5_egypt.kv 372 MustNotZero(Stack(SP));
ffa_ch11_tuning_a... 373 FFA_FZ_Div(Dividend => Stack(SP - 1),
ffa_ch11_tuning_a... 374 Divisor => Stack(SP),
ffa_ch11_tuning_a... 375 Quotient => Stack(SP - 1));
ffa_ch5_egypt.kv 376 Drop;
ffa_ch5_egypt.kv 377
ffa_ch5_egypt.kv 378 -- Divide and give Remainder only
ffa_ch5_egypt.kv 379 when '%' =>
ffa_ch5_egypt.kv 380 Want(2);
ffa_ch5_egypt.kv 381 MustNotZero(Stack(SP));
ffa_ch11_tuning_a... 382 FFA_FZ_Mod(Dividend => Stack(SP - 1),
ffa_ch11_tuning_a... 383 Divisor => Stack(SP),
ffa_ch11_tuning_a... 384 Remainder => Stack(SP - 1));
ffa_ch5_egypt.kv 385 Drop;
ffa_ch5_egypt.kv 386
ffa_ch5_egypt.kv 387 -- Multiply, give bottom and top halves
ffa_ch5_egypt.kv 388 when '*' =>
ffa_ch5_egypt.kv 389 Want(2);
ffa_ch11_tuning_a... 390 FFA_FZ_Multiply(X => Stack(SP - 1),
ffa_ch11_tuning_a... 391 Y => Stack(SP),
ffa_ch11_tuning_a... 392 XY_Lo => Stack(SP - 1),
ffa_ch11_tuning_a... 393 XY_Hi => Stack(SP));
ffa_ch5_egypt.kv 394
ffa_ch4_ffacalc.kv 395 -----------------
ffa_ch4_ffacalc.kv 396 -- Bitwise Ops --
ffa_ch4_ffacalc.kv 397 -----------------
ffa_ch4_ffacalc.kv 398
ffa_ch4_ffacalc.kv 399 -- Bitwise-And
ffa_ch4_ffacalc.kv 400 when '&' =>
ffa_ch4_ffacalc.kv 401 Want(2);
ffa_ch11_tuning_a... 402 FFA_FZ_And(X => Stack(SP - 1),
ffa_ch11_tuning_a... 403 Y => Stack(SP),
ffa_ch11_tuning_a... 404 Result => Stack(SP - 1));
ffa_ch4_ffacalc.kv 405 Drop;
ffa_ch4_ffacalc.kv 406
ffa_ch4_ffacalc.kv 407 -- Bitwise-Or
ffa_ch4_ffacalc.kv 408 when '|' =>
ffa_ch4_ffacalc.kv 409 Want(2);
ffa_ch11_tuning_a... 410 FFA_FZ_Or(X => Stack(SP - 1),
ffa_ch11_tuning_a... 411 Y => Stack(SP),
ffa_ch11_tuning_a... 412 Result => Stack(SP - 1));
ffa_ch4_ffacalc.kv 413 Drop;
ffa_ch4_ffacalc.kv 414
ffa_ch4_ffacalc.kv 415 -- Bitwise-Xor
ffa_ch4_ffacalc.kv 416 when '^' =>
ffa_ch4_ffacalc.kv 417 Want(2);
ffa_ch11_tuning_a... 418 FFA_FZ_Xor(X => Stack(SP - 1),
ffa_ch11_tuning_a... 419 Y => Stack(SP),
ffa_ch11_tuning_a... 420 Result => Stack(SP - 1));
ffa_ch4_ffacalc.kv 421 Drop;
ffa_ch4_ffacalc.kv 422
ffa_ch4_ffacalc.kv 423 -- Bitwise-Not (1s-Complement)
ffa_ch4_ffacalc.kv 424 when '~' =>
ffa_ch4_ffacalc.kv 425 Want(1);
ffa_ch11_tuning_a... 426 FFA_FZ_Not(Stack(SP), Stack(SP));
ffa_ch4_ffacalc.kv 427
ffa_ch4_ffacalc.kv 428 -----------
ffa_ch4_ffacalc.kv 429 -- Other --
ffa_ch4_ffacalc.kv 430 -----------
ffa_ch4_ffacalc.kv 431
ffa_ch8_randomism.kv 432 -- Push a FZ of RNGolade onto the stack
ffa_ch8_randomism.kv 433 when '?' =>
ffa_ch8_randomism.kv 434 Push;
ffa_ch11_tuning_a... 435 FFA_FZ_Clear(Stack(SP));
ffa_ch8_randomism.kv 436 FZ_Random(RNG, Stack(SP));
ffa_ch8_randomism.kv 437
ffa_ch4_ffacalc.kv 438 -- mUx
ffa_ch4_ffacalc.kv 439 when 'U' =>
ffa_ch4_ffacalc.kv 440 Want(3);
ffa_ch11_tuning_a... 441 FFA_FZ_Mux(X => Stack(SP - 2),
ffa_ch11_tuning_a... 442 Y => Stack(SP - 1),
ffa_ch11_tuning_a... 443 Result => Stack(SP - 2),
ffa_ch11_tuning_a... 444 Sel => FFA_FZ_NZeroP(Stack(SP)));
ffa_ch4_ffacalc.kv 445 Drop;
ffa_ch4_ffacalc.kv 446 Drop;
ffa_ch4_ffacalc.kv 447
ffa_ch13_measure_... 448 -- Find the position of eldest nonzero bit, if any exist
ffa_ch13_measure_... 449 when 'W' =>
ffa_ch13_measure_... 450 Want(1);
ffa_ch13_measure_... 451 declare
ffa_ch13_measure_... 452 Measure : Word;
ffa_ch13_measure_... 453 begin
ffa_ch13_measure_... 454 -- Find the measure ( 0 if no 1s, or 1 .. FZBitness )
ffa_ch13_measure_... 455 Measure := FFA_FZ_Measure(Stack(SP));
ffa_ch13_measure_... 456 -- Put on top of stack
ffa_ch13_measure_... 457 FFA_FZ_Clear(Stack(SP));
ffa_ch13_measure_... 458 FFA_FZ_Set_Head(Stack(SP), Measure);
ffa_ch13_measure_... 459 end;
ffa_ch13_measure_... 460
ffa_ch4_ffacalc.kv 461 -- Put the Overflow flag on the stack
ffa_ch4_ffacalc.kv 462 when 'O' =>
ffa_ch4_ffacalc.kv 463 Push;
ffa_ch11_tuning_a... 464 FFA_WBool_To_FZ(Flag, Stack(SP));
ffa_ch4_ffacalc.kv 465
ffa_ch4_ffacalc.kv 466 -- Print the FZ on the top of the stack
ffa_ch4_ffacalc.kv 467 when '#' =>
ffa_ch4_ffacalc.kv 468 Want(1);
ffa_ch11_tuning_a... 469 Print_FZ(Stack(SP));
ffa_ch4_ffacalc.kv 470 Drop;
ffa_ch4_ffacalc.kv 471
ffa_ch4_ffacalc.kv 472 -- Zap (reset)
ffa_ch4_ffacalc.kv 473 when 'Z' =>
ffa_ch4_ffacalc.kv 474 Zap;
ffa_ch4_ffacalc.kv 475
ffa_ch4_ffacalc.kv 476 -- Quit with Stack Trace
ffa_ch4_ffacalc.kv 477 when 'Q' =>
ffa_ch4_ffacalc.kv 478 for I in reverse Stack'First + 1 .. SP loop
ffa_ch11_tuning_a... 479 Print_FZ(Stack(I));
ffa_ch4_ffacalc.kv 480 end loop;
ffa_ch4_ffacalc.kv 481 Quit(0);
ffa_ch4_ffacalc.kv 482
ffa_ch12_karatsub... 483 -- Square, give bottom and top halves
ffa_ch12_karatsub... 484 when 'S' =>
ffa_ch12_karatsub... 485 Want(1);
ffa_ch12_karatsub... 486 Push;
ffa_ch12_karatsub... 487 FFA_FZ_Square(X => Stack(SP - 1),
ffa_ch12_karatsub... 488 XX_Lo => Stack(SP - 1),
ffa_ch12_karatsub... 489 XX_Hi => Stack(SP));
ffa_ch13_measure_... 490
ffa_ch13_measure_... 491 --------------
ffa_ch13_measure_... 492 -- Prefixes --
ffa_ch13_measure_... 493 --------------
ffa_ch13_measure_... 494
ffa_ch13_measure_... 495 -- 'Left...' :
ffa_ch13_measure_... 496 when 'L' =>
ffa_ch13_measure_... 497 IsPrefix;
ffa_ch13_measure_... 498
ffa_ch13_measure_... 499 -- 'Right...' :
ffa_ch13_measure_... 500 when 'R' =>
ffa_ch13_measure_... 501 IsPrefix;
ffa_ch13_measure_... 502
ffa_ch13_measure_... 503 -- 'Modular...' :
ffa_ch13_measure_... 504 when 'M' =>
ffa_ch13_measure_... 505 IsPrefix;
ffa_ch13_measure_... 506
ffa_ch13_measure_... 507 ---------------------------------------------------------
ffa_ch13_measure_... 508 -- Reserved Ops, i.e. ones we have not defined yet: --
ffa_ch13_measure_... 509 ---------------------------------------------------------
ffa_ch13_measure_... 510 when '!' | '@' | '$' | ':' | ';' | ',' |
ffa_ch13_measure_... 511 'G' | 'H' | 'I' | 'J' | 'K' | 'N' |
ffa_ch13_measure_... 512 'P' | 'T' | 'V' | 'X' | 'Y' =>
ffa_ch13_measure_... 513
ffa_ch13_measure_... 514 E("This Operator is not defined yet: " & C);
ffa_ch12_karatsub... 515 ---------------------------------------------------------
ffa_ch12_karatsub... 516
ffa_ch4_ffacalc.kv 517 ----------
ffa_ch4_ffacalc.kv 518 -- NOPs --
ffa_ch4_ffacalc.kv 519 ----------
ffa_ch4_ffacalc.kv 520
ffa_ch13_measure_... 521 -- Unprintables and spaces DO NOTHING:
ffa_ch4_ffacalc.kv 522 when others =>
ffa_ch4_ffacalc.kv 523 null;
ffa_ch4_ffacalc.kv 524
ffa_ch4_ffacalc.kv 525 end case;
ffa_ch4_ffacalc.kv 526
ffa_ch4_ffacalc.kv 527 end Op_Normal;
ffa_ch4_ffacalc.kv 528
ffa_ch4_ffacalc.kv 529
ffa_ch13_measure_... 530 -- Execute a Prefixed Op
ffa_ch13_measure_... 531 procedure Op_Prefixed(Prefix : in Character;
ffa_ch13_measure_... 532 O : in Character) is
ffa_ch13_measure_... 533 begin
ffa_ch13_measure_... 534
ffa_ch13_measure_... 535 -- The Prefixed Op:
ffa_ch13_measure_... 536 case Prefix is
ffa_ch13_measure_... 537
ffa_ch13_measure_... 538 ---------------------------------------------------------
ffa_ch13_measure_... 539 -- Left...
ffa_ch13_measure_... 540 when 'L' =>
ffa_ch13_measure_... 541
ffa_ch13_measure_... 542 -- Which L-op?
ffa_ch13_measure_... 543 case O is
ffa_ch13_measure_... 544
ffa_ch13_measure_... 545 -- ... Shift :
ffa_ch13_measure_... 546 when 'S' =>
ffa_ch13_measure_... 547 Want(2);
ffa_ch13_measure_... 548 declare
ffa_ch13_measure_... 549 -- Number of bit positions to shift by:
ffa_ch13_measure_... 550 ShiftCount : FZBit_Index
ffa_ch13_measure_... 551 := FZBit_Index(FFA_FZ_Get_Head(Stack(SP)));
ffa_ch13_measure_... 552 begin
ffa_ch13_measure_... 553 FFA_FZ_Quiet_ShiftLeft(N => Stack(SP - 1),
ffa_ch13_measure_... 554 ShiftedN => Stack(SP - 1),
ffa_ch13_measure_... 555 Count => ShiftCount);
ffa_ch13_measure_... 556 end;
ffa_ch13_measure_... 557 Drop;
ffa_ch13_measure_... 558
ffa_ch13_measure_... 559 -- ... Rotate :
ffa_ch13_measure_... 560 when 'R' =>
ffa_ch13_measure_... 561 E("Left-Rotate not yet defined!");
ffa_ch13_measure_... 562
ffa_ch13_measure_... 563 -- ... Unknown:
ffa_ch13_measure_... 564 when others =>
ffa_ch13_measure_... 565 E("Undefined Op: L" & O);
ffa_ch13_measure_... 566
ffa_ch13_measure_... 567 end case;
ffa_ch13_measure_... 568 ---------------------------------------------------------
ffa_ch13_measure_... 569 -- Right...
ffa_ch13_measure_... 570 when 'R' =>
ffa_ch13_measure_... 571
ffa_ch13_measure_... 572 -- Which R-op?
ffa_ch13_measure_... 573 case O is
ffa_ch13_measure_... 574
ffa_ch13_measure_... 575 -- ... Shift:
ffa_ch13_measure_... 576 when 'S' =>
ffa_ch13_measure_... 577 Want(2);
ffa_ch13_measure_... 578 declare
ffa_ch13_measure_... 579 -- Number of bit positions to shift by:
ffa_ch13_measure_... 580 ShiftCount : FZBit_Index
ffa_ch13_measure_... 581 := FZBit_Index(FFA_FZ_Get_Head(Stack(SP)));
ffa_ch13_measure_... 582 begin
ffa_ch13_measure_... 583 FFA_FZ_Quiet_ShiftRight(N => Stack(SP - 1),
ffa_ch13_measure_... 584 ShiftedN => Stack(SP - 1),
ffa_ch13_measure_... 585 Count => ShiftCount);
ffa_ch13_measure_... 586 end;
ffa_ch13_measure_... 587 Drop;
ffa_ch13_measure_... 588
ffa_ch13_measure_... 589 -- ... Rotate:
ffa_ch13_measure_... 590 when 'R' =>
ffa_ch13_measure_... 591 E("Right-Rotate not yet defined!");
ffa_ch13_measure_... 592
ffa_ch13_measure_... 593 -- ... Unknown:
ffa_ch13_measure_... 594 when others =>
ffa_ch13_measure_... 595 E("Undefined Op: R" & O);
ffa_ch13_measure_... 596
ffa_ch13_measure_... 597 end case;
ffa_ch13_measure_... 598 ---------------------------------------------------------
ffa_ch13_measure_... 599 -- Modular...
ffa_ch13_measure_... 600 when 'M' =>
ffa_ch13_measure_... 601
ffa_ch13_measure_... 602 -- Which M-op?
ffa_ch13_measure_... 603 case O is
ffa_ch13_measure_... 604
ffa_ch13_measure_... 605 -- ... Multiplication :
ffa_ch13_measure_... 606 when '*' =>
ffa_ch13_measure_... 607 Want(3);
ffa_ch13_measure_... 608 MustNotZero(Stack(SP));
ffa_ch13_measure_... 609 FFA_FZ_Modular_Multiply(X => Stack(SP - 2),
ffa_ch13_measure_... 610 Y => Stack(SP - 1),
ffa_ch13_measure_... 611 Modulus => Stack(SP),
ffa_ch13_measure_... 612 Product => Stack(SP - 2));
ffa_ch13_measure_... 613 Drop;
ffa_ch13_measure_... 614 Drop;
ffa_ch13_measure_... 615
ffa_ch13_measure_... 616 -- ... Exponentiation :
ffa_ch13_measure_... 617 when 'X' =>
ffa_ch13_measure_... 618 Want(3);
ffa_ch13_measure_... 619 MustNotZero(Stack(SP));
ffa_ch13_measure_... 620 FFA_FZ_Modular_Exponentiate(Base => Stack(SP - 2),
ffa_ch13_measure_... 621 Exponent => Stack(SP - 1),
ffa_ch13_measure_... 622 Modulus => Stack(SP),
ffa_ch13_measure_... 623 Result => Stack(SP - 2));
ffa_ch13_measure_... 624 Drop;
ffa_ch13_measure_... 625 Drop;
ffa_ch13_measure_... 626
ffa_ch13_measure_... 627 -- ... Unknown:
ffa_ch13_measure_... 628 when others =>
ffa_ch13_measure_... 629 E("Undefined Op: M" & O);
ffa_ch13_measure_... 630
ffa_ch13_measure_... 631 end case;
ffa_ch13_measure_... 632 ---------------------------------------------------------
ffa_ch13_measure_... 633 -- ... Unknown: (impossible per mechanics, but must handle case)
ffa_ch13_measure_... 634 when others =>
ffa_ch13_measure_... 635 E("Undefined Prefix: " & Prefix);
ffa_ch13_measure_... 636
ffa_ch13_measure_... 637 end case;
ffa_ch13_measure_... 638
ffa_ch13_measure_... 639 end Op_Prefixed;
ffa_ch13_measure_... 640
ffa_ch13_measure_... 641
ffa_ch4_ffacalc.kv 642 -- Process a Symbol
ffa_ch4_ffacalc.kv 643 procedure Op(C : in Character) is
ffa_ch4_ffacalc.kv 644 begin
ffa_ch4_ffacalc.kv 645 -- First, see whether we are in a state of nestedness:
ffa_ch4_ffacalc.kv 646
ffa_ch4_ffacalc.kv 647 -- ... in a Comment block:
ffa_ch4_ffacalc.kv 648 if CommLevel > 0 then
ffa_ch4_ffacalc.kv 649 case C is
ffa_ch4_ffacalc.kv 650 when ')' => -- Drop a nesting level:
ffa_ch4_ffacalc.kv 651 CommLevel := CommLevel - 1;
ffa_ch4_ffacalc.kv 652 when '(' => -- Add a nesting level:
ffa_ch4_ffacalc.kv 653 CommLevel := CommLevel + 1;
ffa_ch4_ffacalc.kv 654 when others =>
ffa_ch4_ffacalc.kv 655 null; -- Other symbols have no effect at all
ffa_ch4_ffacalc.kv 656 end case;
ffa_ch4_ffacalc.kv 657
ffa_ch4_ffacalc.kv 658 -- ... in a Quote block:
ffa_ch4_ffacalc.kv 659 elsif QuoteLevel > 0 then
ffa_ch4_ffacalc.kv 660 case C is
ffa_ch4_ffacalc.kv 661 when ']' => -- Drop a nesting level:
ffa_ch4_ffacalc.kv 662 QuoteLevel := QuoteLevel - 1;
ffa_ch4_ffacalc.kv 663 when '[' => -- Add a nesting level:
ffa_ch4_ffacalc.kv 664 QuoteLevel := QuoteLevel + 1;
ffa_ch4_ffacalc.kv 665 when others =>
ffa_ch4_ffacalc.kv 666 null; -- Other symbols have no effect on the level
ffa_ch4_ffacalc.kv 667 end case;
ffa_ch4_ffacalc.kv 668
ffa_ch4_ffacalc.kv 669 -- If we aren't the mode-exiting ']', print current symbol:
ffa_ch4_ffacalc.kv 670 if QuoteLevel > 0 then
ffa_ch4_ffacalc.kv 671 Write_Char(C);
ffa_ch4_ffacalc.kv 672 end if;
ffa_ch4_ffacalc.kv 673
ffa_ch4_ffacalc.kv 674 --- ... in a ~taken~ Conditional branch:
ffa_ch4_ffacalc.kv 675 elsif CondLevel > 0 then
ffa_ch4_ffacalc.kv 676 case C is
ffa_ch4_ffacalc.kv 677 when '}' => -- Drop a nesting level:
ffa_ch4_ffacalc.kv 678 CondLevel := CondLevel - 1;
ffa_ch4_ffacalc.kv 679
ffa_ch4_ffacalc.kv 680 -- If we exited the Conditional as a result,
ffa_ch4_ffacalc.kv 681 -- we push a 1 to trigger the possible 'else' clause:
ffa_ch4_ffacalc.kv 682 if CondLevel = 0 then
ffa_ch4_ffacalc.kv 683 Push;
ffa_ch11_tuning_a... 684 FFA_WBool_To_FZ(1, Stack(SP));
ffa_ch4_ffacalc.kv 685 end if;
ffa_ch4_ffacalc.kv 686
ffa_ch4_ffacalc.kv 687 when '{' => -- Add a nesting level:
ffa_ch4_ffacalc.kv 688 CondLevel := CondLevel + 1;
ffa_ch4_ffacalc.kv 689 when others =>
ffa_ch4_ffacalc.kv 690 null; -- Other symbols have no effect on the level
ffa_ch4_ffacalc.kv 691 end case;
ffa_ch13_measure_... 692
ffa_ch13_measure_... 693 --- ... if in a prefixed op:
ffa_ch13_measure_... 694 elsif HavePrefix then
ffa_ch13_measure_... 695
ffa_ch13_measure_... 696 -- Drop the prefix-op hammer, until another prefix-op cocks it
ffa_ch13_measure_... 697 HavePrefix := False;
ffa_ch13_measure_... 698
ffa_ch13_measure_... 699 -- Dispatch this op, where prefix is the preceding character
ffa_ch13_measure_... 700 Op_Prefixed(Prefix => PrevC, O => C);
ffa_ch13_measure_... 701
ffa_ch4_ffacalc.kv 702 else
ffa_ch4_ffacalc.kv 703 -- This is a Normal Op, so proceed with the normal rules.
ffa_ch4_ffacalc.kv 704 Op_Normal(C);
ffa_ch4_ffacalc.kv 705 end if;
ffa_ch4_ffacalc.kv 706
ffa_ch4_ffacalc.kv 707 end Op;
ffa_ch4_ffacalc.kv 708
ffa_ch4_ffacalc.kv 709
ffa_ch4_ffacalc.kv 710 -- Current Character
ffa_ch4_ffacalc.kv 711 C : Character;
ffa_ch4_ffacalc.kv 712
ffa_ch4_ffacalc.kv 713 begin
ffa_ch4_ffacalc.kv 714 -- Reset the Calculator
ffa_ch4_ffacalc.kv 715 Zap;
ffa_ch4_ffacalc.kv 716 -- Process characters until EOF:
ffa_ch4_ffacalc.kv 717 loop
ffa_ch4_ffacalc.kv 718 if Read_Char(C) then
ffa_ch4_ffacalc.kv 719 -- Execute Op:
ffa_ch4_ffacalc.kv 720 Op(C);
ffa_ch4_ffacalc.kv 721 -- Advance Odometer
ffa_ch4_ffacalc.kv 722 Pos := Pos + 1;
ffa_ch13_measure_... 723 -- Save the op for use in prefixed ops
ffa_ch13_measure_... 724 PrevC := C;
ffa_ch4_ffacalc.kv 725 else
ffa_ch4_ffacalc.kv 726 Zap;
ffa_ch4_ffacalc.kv 727 Quit(0); -- if EOF, we're done
ffa_ch4_ffacalc.kv 728 end if;
ffa_ch4_ffacalc.kv 729 end loop;
ffa_ch4_ffacalc.kv 730 end;
ffa_ch4_ffacalc.kv 731
ffa_ch4_ffacalc.kv 732 end FFA_Calc;