Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Runer112

Pages: 1 ... 73 74 [75] 76 77 ... 153
1111
This is a very extensive and well-written tutorial. But I have some questions/concerns about some of these topics and code structures.


  • Lambdas in Axe are, for all intents and purposes, slightly bloated subroutines (due to the jump past the routine). I realize that lambdas have other qualifying features like ease of inserting inline, but I feel that the fact that they produce slightly larger code than a standard subroutine is worth being mentioned.


  • Regarding closures and currying, as far as I can tell, code would be more optimized simply without these techniques. I think code also looks cleaner without the unnecessary nesting. If you can give me a counter-example, I would love to see it. But regarding the examples you used, compare these:

Code: (Independent closure; 54 bytes) [Select]
Lbl CAT
  r₁+r₂→r₄
  DOG(r₁,r₂,r₃,r₄)
  Goto DOGE
  Lbl DOG
    r₄+r₃
    Return
  Lbl DOGE
  →r₁
  Return
Lbl CATE
   
Code: (Two separate routines; 51 bytes) [Select]
Lbl CAT
  r₁+r₂→r₄
  DOG(r₁,r₂,r₃,r₄)
  →r₁
  Return
Lbl CATE

Lbl DOG
  r₄+r₃
  Return
Lbl DOGE

Code: (Currying; 62 bytes) [Select]
λ(r₁*(λ(r₁+r₂)(r₁,r₂)))(r₁,r₂)
   
Code: (No currying; 38 bytes) [Select]
λ((r₁+r₂)*r₁)(r₁,r₂)


  • A big reason why the example above without currying is so much smaller is because it omitted an argument list due to one of the functions being eliminated. This is something that you should do in multiple other places as well. Calling a function with the r-vars as arguments is redundant, because all it does is load the r-vars and then save them back where they already were. For example, λ((r₁+r₂)*r₁)(r₁,r₂) could be λ((r₁+r₂)*r₁)() to save 12 bytes, and DOG(r₁,r₂,r₃,r₄) could simply be DOG() to save a massive 24 bytes.


VIII - Returning multiple values

WARNING -- THE FOLLOWING PROCEDURE IS POSSIBLY DANGEROUS IF USED INCORRECTLY.
  • (Ninja'd by calcdude84se) Your procedure is dangerous if used at all. You push the second value to return on top of the return address, so the Return will read the wrong value and almost certainly crash or otherwise negatively affect your calculator. You need to keep the return address at the top of the stack and push extra return values under it:

Code: [Select]
Lbl HACK
  r₁+r₂
  Asm(E3E5)    . ex (sp),hl \ push hl
  r₂*r₁
Return



Also, a suggestion to make code look cleaner. Fish around in this for special characters on the calculator:
Spoiler For Special Characters:


ʟ
L₁
L₂
L₃
L₄
L₅
L₆
r₁
r₂
r₃
r₄
r₅
r₆
Y₁
Y₂
Y₃
Y₄
Y₅
Y₆
Y₇
Y₈
Y₉
Y₀
°
∆List(



·


⁻¹
²
³
√(
³√(
ˣ√


ʳ
►Dec
►Frac
►Char
►DMS
►Tok
►Rect
►Hex
θ
α
β
γ
Δ
δ
ε
λ
μ
π
ρ
Σ
Φ
Ω

χ
σ
τ



ß
ˣ




×


ȳ


1112
The Axe Parser Project / Re: Bug Reports
« on: July 15, 2011, 10:13:44 pm »
'appv' is not parsed as 15h, unlike it is when in a string. This should probably be changed to return the same ASCII value it would represent in a string. The same probably goes for 'var' and 'grp'.


EDIT: Also, an entirely unrelated bug. B_CALL(_DelVarArc) apparently trashes (OP1) if the variable was archived, so attempting to create a variable that already exists in the archive deletes the old one and then fails to create the new one. Luckily, this is easily fixable. I found a solution that I think is as good as it gets, but I could be wrong. It only costs a single byte.

Code: [Select]
p_NewVar:
.db __NewVarEnd-1-$
B_CALL(_EnoughMem)
pop hl
ex (sp),hl
jr c,__NewVarFail
push de
push hl
MOV9TOOP1()
B_CALL(_ChkFindSym)
jr c,__NewVarSkip
B_CALL(_DelVarArc)
__NewVarSkip:
pop hl
ld a,(hl)
MOV9TOOP1()
pop hl
push af
B_CALL(_CreateVar)
pop af
ex de,hl
and %00011111
ret z
cp CplxObj
ret z
inc hl
inc hl
ret
__NewVarFail:
ld hl,0
ret
__NewVarEnd:

1113
Also, I found it a bit annoying that when I did something like If E<(96*256), the part in the parentheses wasn't reduced to a constant before doing the less-than operation. Could the look-ahead parsing be able to detect constants in parentheses?

This times a million.

1114
The Axe Parser Project / Re: Features Wishlist
« on: July 14, 2011, 08:12:37 pm »
In addition to structs, another nice feature would be expression continuation over multiple lines.  Take this for example:

Code: [Select]
lambda(Pt-on(r1,r2,r3):Pt-on(r1,r2+8,r3+8)) -> A
It would be nice if when a line ends with a colon, the expression isn't closed at the end of the line, but rather continued on the next one:

Code: [Select]
lambda(Pt-on(r1,r2,r3):
Pt-on(r1,r2+8,r3+8)) ->A

I'm finding myself writing long lambdas ATM for TaN (don't yell at me for making it Axe based again, I only did it because the new functional features make life so much easier considering enemies), some of which take dozens of lines.  This addition would be very helpful :)

You could just write the function as a subroutine and then deference the pointer to the subroutine.

1115
The Axe Parser Project / Re: Axe Parser
« on: July 13, 2011, 12:31:44 pm »
The reason why code and data are separated is because these recent developments you speak of require either a dedicated program to enforce this setting or an OS/boot code mod. I think most calculator gamers are just students who learned from other students that you can put cool games on your calculator. They probably have no knowledge of these recent developments regarding the execution limit, and will be complaining upon discovering that the game he put on his calculator causes a crash.

EDIT: Oh, I forgot. Or you can add ~50 bytes of code to do this in large programs, which may be completely unnecessary if the code is just moved around a bit.

1116
The Axe Parser Project / Re: Bug Reports
« on: July 13, 2011, 11:33:47 am »
Not all of what follows are bug reports, but I figured it's just easier to make one post here instead of 3 posts across multiple topics.


Some errors in the command list:

  • Returnrr should be Returnr
  • The description of the new Fill() command says "Ptr1" although it should say "Ptr"
  • The grayscale DispGraphClrDraw commands are not as fast as their non-clearing counterparts. The 3-level variant is about 4,000 cycles slower and the 4-level variant is about 11,000 cycles slower. You probably don't want to be technical and cite these numbers in the command list, but you shouldn't say that they're just as fast.

Some actual errors:

  • Inline if statements (and I mean actual inline If:.true:End statements) seem to cause problems if they are inside of the argument list for Axe commands.
  • Shade() does not load a 0 into the h register. I'm guessing you left this out because in most uses, it wouldn't matter. But it could still matter in some, like testing if the value is greater than, less than, or equal to a certain value.

An optimization:

  • Operations on big-endian values at constant pointers (e.g. +{°A}rr) would be better as: ld bc,(ptr) \ ld d,c \ ld e,b

A suggestion:

  • A checksum routine that's more than a simple checksum. Here's a CRC-CCITT implementation I wrote. And no, I actually didn't realize z80 bits had one just like this until after I had written it.
Code: [Select]
p_CheckSum:
ld b,h
ld c,l
pop af
pop de
push af
ld hl,$FFFF
__CheckSumNext:
ld a,(de)
xor h
ld h,a
push bc
ld bc,8<<8+$10
__CheckSumLoop:
add hl,hl
jr nc,__CheckSumSkip
ld a,h
xor c
ld h,a
ld a,l
xor $21
ld l,a
__CheckSumSkip:
djnz __CheckSumLoop
pop bc
ex de,hl
cpi
ex de,hl
ret po
jr __CheckSumNext

    1117
    The Axe Parser Project / Re: Features Wishlist
    « on: July 13, 2011, 10:45:43 am »
    To make the string "123@456", you would do something like the following. 40 is the hexadecimal character code for @.

    Code: [Select]
    "123"[40]"456"

    1118
    Just checking, have you actually tested the routines out? Because I didn't actually test those routines I gave you, I just modeled them after some routines I knew worked and hoped these would still work as well. :P

    1119
    Wow, I just did something I didn't think was even possible. I found a good use for a forward djnz. *.*

    The following is the part of p_Disp4Lvl that initializes the mask:

    Code: (17 bytes, ~62 cycles) [Select]
    ld a,%11011011
    or a
    ld hl,flags+asm_flag2
    inc (hl)
    jr z,__Disp4Lvlskip
    rra
    ld b,(hl)
    inc b
    jr z,__Disp4Lvlskip
    rra
    ld (hl),-2
       
    Code: (16 bytes, ~60 cycles) [Select]
    ld a,%11011011
    or a
    ld hl,flags+asm_flag2
    inc (hl)
    jr z,__Disp4Lvlskip
    rra
    ld b,(hl)
    djnz __Disp4Lvlskip
    rra
    ld (hl),-2

    1120
    Axe / Re: Axe Q&A
    « on: July 11, 2011, 08:55:55 pm »
    That, and my independent documentation of Axe's commands. These are the optimized signed divisions that will round down instead of to zero:

    • //2
    • //64
    • //128
    • //256
    • //512
    • //16384
    • //32768

    1121
    Axe / Re: Axe Q&A
    « on: July 11, 2011, 08:31:07 pm »
    In Axe, calculations that would generate decimals, such as division, will always be truncated. When dealing with positive numbers, this means results are rounded down. However, with negative numbers, the story changes slightly depending upon how the math is performed.

    With something like ⁻10//3, the signed division routine converts any negative inputs to positives and then corrects the sign later. So it actually calculates the result of 10/3 which gives 3 due to truncation, but then negating the final answer to correct for the signs results in the answer actually having been rounded to zero from -3.333...

    However, with optimized divisions like ⁻7//2, the inputs are not first converted to positive numbers and then operated on, resulting in the truncation actually rounding down to ⁻4.


    In summary:
    • Normal division: rounds to zero (down)
    • Signed division: rounds to zero (not always down)
    • Signed disivion by optimized constants: rounds down

    1122
    Axe / Re: Getkey Routine
    « on: July 11, 2011, 08:18:49 pm »
    Ah! Now it works better!
    But there a new problem  :-\
    If I go up or left, I'm on the other side...
    Do you understand me?  :P

    Oh sorry, I found the problem and corrected it. I needed to check if the position became negative one before performing the min function. Check the code again, hopefully it should work now.

    1123
    Axe / Re: Getkey Routine
    « on: July 11, 2011, 02:10:40 pm »
    Really!? :w00t:

    1124
    Axe / Re: Getkey Routine
    « on: July 11, 2011, 11:22:21 am »
    I don't get it work :(

    Oh sorry, I typoed when copying that code from my calculator to here. +getKey(4) and +getKey(2) should be -getKey(4) and -getKey(2).


    Wait, so +{const}r isn't optimized automatically? :O

    Nope. It bugs me a bit that Axe doesn't recognize those and parse them just like variables. I'm guessing Quigibo hasn't included them because he would need some sort of look-ahead parsing for that, which he hasn't implemented.

    1125
    My calculator does not have a ViewScreen port. Otherwise, it seems to be pretty much the same.

    Pages: 1 ... 73 74 [75] 76 77 ... 153