code logs -> 2007 -> Tue, 27 Nov 2007< code.20071126.log - code.20071128.log >
--- Log opened Tue Nov 27 00:00:05 2007
00:09
<@ToxicFrog>
Generating actual VM bytecode is waaaaay too hair, especially from Lua proper, which doesn't do so well with raw binary manipulation.
00:10
<@McMartin>
Quite so
00:10
<@McMartin>
Also, more opportunities to mess up.
00:12
<@ToxicFrog>
It's a performance hit, but BFD, you only do it once.
00:34 Derakon[AFK] is now known as Derakon
00:34
<@Derakon>
Evening, all.
01:24
<@McMartin>
'lo
01:57 You're now known as TheWatcher[T-2]
02:01
<@Derakon>
Seeya, TW.
02:01 You're now known as TheWatcher[zZzZ]
03:07 Derakon is now known as Derakon[AFK]
03:17 Vornicus-Latens is now known as Vornicus
03:22 * Vornicus fiddles with PyGame.
03:31
<@Vornicus>
Tools that are awesome: ResEdit.
03:34
<@Vornicus>
Hrm. Is there an Un-hexdump?
03:34
<@Vornicus>
Or do I have to write that myself?
03:40
<@Vornicus>
''.join(chr(int(hi+lo,16)) for hi, lo in zip(hexpile[0::2],hexpile[1::2]))
03:40
<@Vornicus>
Ah well, it's a one liner.
03:44
<@McMartin>
Snerk.
03:44
<@McMartin>
Yeah, more or less
03:44
<@McMartin>
(See also struck.pack and struct.unpack, though)
03:45
<@Vornicus>
Struct actually appears to be harder to use in this case.
03:52 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has quit [Ping Timeout]
03:53 Forj [~Forj@Nightstar-10789.ue.woosh.co.nz] has joined #code
03:53 mode/#code [+o Forj] by ChanServ
03:58
<@McMartin>
Yeah, struct isn't what you want here.
03:58
<@McMartin>
Just reminding you that it exists and thus you aren't restricted to ord and chr
03:59 * Vornicus is using struct now, since he's got the data into binary.
04:01 * Vornicus <3 struct.
04:03
<@McMartin>
Yes
04:03
<@McMartin>
That's also the first I've seen the :: syntax actually used.
04:04
<@Vornicus>
heh
04:12
<@ToxicFrog>
Hmm.
04:13
<@ToxicFrog>
Writing a parser for Lua isn't terribly hard.
04:13
<@ToxicFrog>
Writing a parser that parses Lua by default but is modifiable at runtime is.
04:16 * Vornicus makes his computer spew a vaguely human-readable map.
04:17
<@Vornicus>
Well, sorta - it's a lot of ?s right now because I don't know what the individual bytes are.
04:18
<@ToxicFrog>
Mmm, bootstrapping
04:18
<@ToxicFrog>
-- self test
04:18
<@ToxicFrog>
table.print(lexer:lex(io.open(arg[0],'r'):read('*a')))
04:37 Vornotron [~vorn@Admin.Nightstar.Net] has joined #code
04:37 Vornicus [~vorn@Admin.Nightstar.Net] has quit [Ping Timeout]
04:37 Vornotron is now known as Vornicus
04:38 GeekSoldier|bed is now known as GeekSoldier|work
04:51 Derakon[AFK] is now known as Derakon
05:13 * Vornicus fiddles, get closer to completing his list of objects on the world map.
05:18 mode/#code [+o Vornicus] by Vornicus
05:18
<@Vornicus>
http://vorn.dyndns.org/~vorn/kb_continentia.txt
05:21
<@Vornicus>
67 distinct symbols in the text (6 castles, three grasslands, 13 each mountain forest desert, 14 water, and 5 specials)
05:26
<@ToxicFrog>
Nice.
05:27
<@Vornicus>
Now I get to extract the other three continents, and then my next job will be to make extremely basic (like, 8x8px, solid colors) graphics for each thing.
05:28
<@ToxicFrog>
Yay postscript!
05:28
<@ToxicFrog>
I think I've nailed down the format for my parser.
05:28
<@ToxicFrog>
Each parser node is either:
05:28
<@ToxicFrog>
- a function, which consumes some number of tokens from the token stream an returns an AST, possibly calling other nodes in the process
05:29
<@ToxicFrog>
- an object, consisting of a dispatch table mapping token sequences to parser nodes, which chooses a node to call based on the next N tokens in the stream
05:29
<@Vornicus>
Yay postscript
05:30
<@ToxicFrog>
Sound sane?
05:30
<@Vornicus>
I don't really know.
05:32
<@ToxicFrog>
...oh, goddamnit.
05:32
<@ToxicFrog>
The Lua grammar is left-recursive.
05:33
<@ToxicFrog>
...or not.
05:36
<@McMartin>
Left recursion can always be factored away
05:40
<@ToxicFrog>
Well, it's actually:
05:40
<@ToxicFrog>
statement := functioncall | ...
05:41
<@ToxicFrog>
functioncall := prefixexp args
05:41
<@ToxicFrog>
prefixexp := var | functioncall | '(' exp ')'
05:41
<@ToxicFrog>
So you can go functioncall => prefixexp => functioncall forever, if you aren't careful
05:42
<@McMartin>
Well, yes
05:42
<@McMartin>
Because that grammar is left-recursive
05:42
<@McMartin>
You can always to partial expansion to the point where each production starts with a unique terminal.
05:42
<@McMartin>
There's an algorithm in the Dragon Book.
05:42
<@ToxicFrog>
My parser theory is really rusty ;.;
05:42
<@ToxicFrog>
I think I need to reread that part of the Dragon Book.
05:43
<@McMartin>
It's kind of a royal pain in the ass, so you're really better off just adding more lookahead
05:43
<@ToxicFrog>
Yeah, my framework supports arbitrary quantities of lookahead, so I may just do that.
05:43
<@ToxicFrog>
It's been suggested I use LR instead, but LR parsers are a pain to write.
05:43
<@McMartin>
Just watch out for precedence.
05:43
<@McMartin>
LR parsers are insanely difficult to write and nearly impossible to get to give decent error messages.
05:45
<@ToxicFrog>
Yeah. Which is why everything that uses LR uses a parser generator to produce it.
05:46
<@ToxicFrog>
The bulk of the dragon book is devoted to LR, though.
05:47
<@McMartin>
Well
05:47
<@McMartin>
The bulk of the parsing chapter.
05:48
<@McMartin>
That's because there isn't a Hell of a lot to say about LL grammars, they being vastly simpler.
05:49 * Vornicus fiddles with PIL.
06:01
<@McMartin>
PIL?
06:17
<@Vornicus>
Python Imaging Library
06:25
<@McMartin>
Aha
06:32 * McMartin makes a first cut at a global resource map for UQM: http://www.stanford.edu/~mcmartin/resourcemap1.txt
06:50 Pi [~sysop@Nightstar-24414.hsd1.wa.comcast.net] has joined #code
06:50 mode/#code [+o Pi] by ChanServ
06:55 * Vornicus gets Python to do his unspeakable bidding.
06:56 * Vornicus then goes to get the other three continent data files.
06:58 Derakon is now known as Derakon[AFK]
08:52 Thaqui [~Thaqui@Nightstar-26276.jetstream.xtra.co.nz] has left #code [Leaving]
09:11 * McMartin tracks down a GW-BASIC compiler for his own Christmas project.
09:13 Vornicus [~vorn@Admin.Nightstar.Net] has quit [Ping Timeout]
09:22 Vornicus [~vorn@Admin.Nightstar.Net] has joined #code
09:22 mode/#code [+o Vornicus] by ChanServ
09:36 You're now known as TheWatcher[
09:36 You're now known as TheWatcher
09:49 Chalcedon [~Chalcedon@Nightstar-10789.ue.woosh.co.nz] has quit [Quit: Gone]
09:52 Forj [~Forj@Nightstar-10789.ue.woosh.co.nz] has quit [Quit: Gone]
10:13 * Vornicus finishes hunting down such things as sign texts and castle and town locations.
10:13
<@McMartin>
w00t
10:13
<@McMartin>
You missed my finding a GW-BASIC compiler for my own Christmas present
10:13
<@Vornicus>
w00y
10:13
<@Vornicus>
only spelled right
10:14
<@Reiver>
...That's a pretty sweet trick, McM
10:14 * Vornicus did this hunting by playing the game.
10:14
<@McMartin>
Reiver: Not really, it was one Google Search.
10:16
<@Reiver>
I more mean, uh
10:16
<@Reiver>
The existance thereof is pretty sweet. Er. It made sense in my head. *sigh*
10:16
<@McMartin>
They've been around forever
10:16 * Reiver 's brain is not working so hot today.
10:16
<@McMartin>
They are why Paul Allen Panks keeps polluting the IFComp.
10:16
<@Reiver>
?
10:17
<@McMartin>
Every year he submits three terribly written adventure games written in BASIC.
10:17
<@Vornicus>
Paul Allen Panks. Incredibly bad IF writer.
10:17
<@Vornicus>
Thinks he's the best ever.
10:17
<@McMartin>
Is on antipsychotics.
10:18
<@Reiver>
Uh... huh.
10:19
<@Reiver>
The latter tidbit came to be revealed how?
10:19
<@McMartin>
He claimed it once on Usenet, and nobody has any reason to doubt it
10:21
<@Reiver>
Healthy.
10:22
<@MyCatVerbs>
Huh. What's standard operating procedure for when one misses a lecture, only to find out that the lecture was actually an hour later and will now be trivial to arrive at on time?
10:23
<@MyCatVerbs>
Should I dance a jig, or would it be a better idea to just keep quiet?
10:23
<@Reiver>
One pretends it was planned all along.
10:27
<@Vornicus>
...oh, that's why my numbers are wrong. I got them out of divmod backwards.
10:27
<@Vornicus>
Sigh.
10:28
<@MyCatVerbs>
Reiver: huh. The siamese kitten approach, I see.
10:32 * Vornicus fiddles. This information is easy to present (since signs, towns, and castles are permanent fixtures on the game board and have their locations coded into the game board data, I need only look it up when the character arrives; monsters and treasure are a bit harder)
10:44
<@Vornicus>
Okay. The only hard bit in this segment is handling updates of monster and monster-treasure positions.
10:54 * Reiver wishes he could find nice, clean formulas.
10:55
<@Vornicus>
For what?
10:55
<@Reiver>
Oh, er. SEV has technology trees, right, where you can upgrade certain techs, and have level-based statistics that improve accordingly.
10:56
<@Vornicus>
okay.
10:56
<@Reiver>
For a certain set of components, what I actually want is minaturization - they start off huge, requiring dedicated large scale vehicles to deploy, and then after, eh, I dunno, 3-6 techs or something, they've ended up small enough to be thrown almost as an addon to your utility craft.
10:58
<@Reiver>
I'd sort of like to find a formula that let you go, say, 100 60 40 30 25 20, or 1000 600 200 100 50 etc.
10:58
<@Reiver>
The whole 1/x style curve, where there's a definate 'sweet spot' to the design.
10:59
<@Reiver>
However, these curves need to be done formulatically.
10:59
<@Reiver>
And due to a game design decision, I'd really rather they were 'clean' numbers, if that parses.
11:06
<@Vornicus>
YOu want nice round numbers.
11:07
<@Vornicus>
<weilawei> Vornicus, i think it's python rite of passage. you must write tons of code only to be told theres already a function for that. *cough*batteries included*cough*
11:07
<@Vornicus>
<Vornicus> Eh. That was only one line of code.
11:07
<@Vornicus>
<Vornicus> Now, if Python happens to have the combat damage algorithm from King's Bounty hiding in it, I'll be /really/ impressed.
11:07
<@Vornicus>
<weilawei> Vornicus, hang on lemme send you my patched source for py3k O:-)
11:07
<@Vornicus>
<Vornicus> *snrrrrrk*
11:07
<@Vornicus>
<weilawei> Vornicus, also, beware, i've changed the print statement a bit. it now launches a game of MULE instead of clobbering your screen with all that useless junk.
11:07
<@McMartin>
Which one line was that? The unhexer?
11:08
<@McMartin>
I guess you could int('0x'+hexstr) too.
11:08
<@Vornicus>
Wouldn't have worked, really - this was 4096 bytes of hex.
11:08
<@Vornicus>
output bytes.
11:09
<@Reiver>
Yeah, I want nice round numbers.
11:10
<@Reiver>
I happen to know that the software in question truncates non-integers in the section I'm dealing with, so it may be possible to exploit that, maybe.
11:10
<@Reiver>
(As in, work in smaller magnitudes, then multiply the whole lot by 10 or something afterwards)
11:10
<@Vornicus>
You might be able to do that - do you have log10?
11:11
<@Reiver>
I know we have sqrt...
11:11
<@Reiver>
It's python script, only without the ability to include extra functions.
11:11
<@Reiver>
So if sqrt and log10 are in the same set of includes, sure~
11:12 * Vornicus fiddles. def nice_round_number(k): return floor(k/floor(log10(k))) * floor(log10(k))
11:12
<@Vornicus>
they're both in math
11:13
<@Reiver>
Right then.
11:13 * Reiver is not certain if we can do defs - these are configuration files, the math is parsed along one line of code.
11:14
<@Reiver>
Granted, the lines of code can be, uh Weapon Space Max Damage Modifier Formula := (48 + (([%Level%] - 1) * 4)) - ([%Range%] * 0.2) - iif([%Range%] > Min(100, (([%Level%] - 1) * 3) + 70), 10000, 0)
11:14
<@Reiver>
>.>
11:14 GeekSoldier|work [~Rob@Nightstar-4430.pools.arcor-ip.net] has quit [Ping Timeout]
11:15
<@Vornicus>
Well, that's something you can just drop in, mostly.
11:15
<@Reiver>
Where? I don't think it parses lines of code that don't have a specified place, but I could give it a go.
11:16 GeekSoldier|work [~Rob@Nightstar-4430.pools.arcor-ip.net] has joined #code
11:16
<@Vornicus>
I mean in the sense of, you can take however you define k, and drop it into that function.
11:17
<@Reiver>
Oh, right
11:17
<@Vornicus>
So you'd go, for instance: floor((1000/%Level%)/floor(log10(1000/%Level%))) * floor(log10(1000/%Level%)
11:18 * Reiver nods.
11:18
<@Reiver>
(floor does what?)
11:18
<@Reiver>
(For that materr, what does that thing do?)
11:19
< GeekSoldier|work>
floor returns 12 if given 12.802
11:19
<@Vornicus>
floor: the highest integer no greater than the number given to it.
11:19
<@Reiver>
Ach!
11:19
<@Reiver>
So kinda like truncation, then? >.>
11:20
< GeekSoldier|work>
yeah.
11:20
<@Vornicus>
Exactly like truncation, except truncation usually goes toward 0, and floor usually goes toward -inf
11:20
< GeekSoldier|work>
actually, it returns 12.0
11:20
< GeekSoldier|work>
and -13.0 if given -12.802
11:21
<@Reiver>
Ahhh.
11:22
<@Vornicus>
So what it does is, it divides k by the largest power of 10 it can, then cuts off all the crap after the decimal point, then multiplies it by the original power of 10.
11:23 gnolam [lenin@Nightstar-10613.8.5.253.static.se.wasadata.net] has joined #Code
11:23 mode/#code [+o gnolam] by ChanServ
11:23
<@Reiver>
Thus giving me a nice round number.
11:24
<@Reiver>
...Ah, this is rounding to 1sf, isn't it?
11:24
<@Reiver>
No. Truncating.
11:25
<@Vornicus>
replace the first floor with round and you get it rounding.
11:25 * Reiver fiddles, tries to see what sort of numbers he can get outta this.
11:25
<@Reiver>
(Really, the first step is trying to find a formula that does roughly the sizes I was after.)
11:54 GeekSoldier|work [~Rob@Nightstar-4430.pools.arcor-ip.net] has quit [Ping Timeout]
12:01 GeekSoldier|work [~Rob@Nightstar-4430.pools.arcor-ip.net] has joined #code
12:12 GeekSoldier|work [~Rob@Nightstar-4430.pools.arcor-ip.net] has quit [Ping Timeout]
12:21
<@Vornicus>
You may just wish to actually figure out the numbers you want and then drop them in to the thing as a list.
12:36
<@gnolam>
My code! My beautiful beautiful code! Spoiled
12:36
<@gnolam>
!
12:36
<@gnolam>
Ruined!
12:36
<@gnolam>
Defiled!
12:38 * Vornicus is sorry.
13:07 You're now known as TheWatcher[afk]
13:23 You're now known as TheWatcher
14:42
<@ToxicFrog>
Hmm. Ok, here's the problem I'm having.
14:42
<@ToxicFrog>
Say I want to parse: foo(2)
14:42
<@ToxicFrog>
This turns into NAME(foo) '(' NUMBER(2) ')'
14:43
<@ToxicFrog>
The statement parser hands things over to the name parser, which looks ahead one, sees '(', and hands things over to the function call parser, which constructs an appropriate AST and everyone's happy.
14:43
<@ToxicFrog>
But now consider: foo[1](2)
14:44
<@ToxicFrog>
The name parser looks ahead one, sees '[', and invokes the table index parser
14:44
<@ToxicFrog>
And once that's finished, I have a tableindex { name=NAME(foo), index=NUMBER(1) } AST, and (2) still in the token stream
14:45
<@ToxicFrog>
Where what needs to happen is it needs to parse it into functioncall { name=tableindex {...}, args = {2} }
14:45
<@ToxicFrog>
But I can't see how to fix this without adding infinite lookahead.
14:49
<@ToxicFrog>
...hmm. Unless the statement parser re-invokes itself until it actually has a complete valid statement
14:50
<@ToxicFrog>
But then foo[1](2)() doesn't get parsed right, because foo[1](2) is a valid statement...so it actually has to keep invoking itself until (1) it has a valid statement, and (2) it can't make it any longer while keeping it valid
15:00
<@Vornicus>
Okay, um
15:01
<@Vornicus>
Are you telling me that Lua does not have an unambiguous statement terminator?
15:01
<@ToxicFrog>
(I think I can do this with only 1-token lookahead)
15:01
<@ToxicFrog>
Nope. It does if you're using ;, but that's optional
15:02
<@Vornicus>
A thing that goes "what can I expect next?" is probably your best bet.
15:03
<@ToxicFrog>
Well, once it's parsed foo[1], it could expect anything of .bar (tableindex) :bar(...) (methodcall) (...) (functioncall) [...] (tableindex) "..." (functioncall) {...} (functioncall) ,... (assignment-list)
15:04
<@ToxicFrog>
In the case of ',', it resolves the entire statement to assignment-list and calls the AL parser
15:04
<@Vornicus>
But you can't expect a name.
15:04
<@ToxicFrog>
Correct.
15:04
<@ToxicFrog>
Oh, it could also expect =
15:05
<@ToxicFrog>
Which would also make it an assignment-list
15:05
<@ToxicFrog>
But yes, a NAME would mean the next statement (and would be a parse error; foo[1] isn't a valid statement on its own) and a NUMBER is just a parse error period, as would most operators be in that context.
15:06
<@ToxicFrog>
All operators, actually, since it's parsing a statement, not an expression.
15:11
<@ToxicFrog>
I think this works with the statement parser dispatch table just fine, actually
15:11
<@ToxicFrog>
...oh, wait.
15:12
<@ToxicFrog>
Wait, no, that still works, because OPAREN => expression happens above it.
15:13
<@ToxicFrog>
So OBRACKET and DOT => tableindex, OPAREN, STRING and OBRACE => function call, COLON => methodcall, LET or COMMA => assignment-list.
15:14
<@ToxicFrog>
Anything else is end-of-statement if it has a valid function call, method call, or assignment-list, and is a parse error otherwise.
15:15
<@Vornicus>
Just keep going until you get to something that makes you go "wait, I wasn't expecting that..."
15:15
<@Vornicus>
There are only so many ways a statement can begin, and as far as I'm aware the only thing a statement can begin with is a name.
15:15
<@ToxicFrog>
Well. Discounting keyword-triggered statements (flow control, local and function declarations), which are dispatched seperately...
15:16
<@ToxicFrog>
A statement can start either with a name, or with an (expression)
15:16
<@ToxicFrog>
Although in the latter case it has to turn into tableindex, functioncall, or methodcall.
15:17
<@ToxicFrog>
The (expression) bit is actually the only ambiguity in the language - if you have:
15:17
<@ToxicFrog>
foo(...)(...).bar(...)
15:18
<@ToxicFrog>
Is that what it looks like, or is it two statements:
15:18
<@ToxicFrog>
foo(...)
15:18
<@ToxicFrog>
(...).bar(...)
15:18
<@ToxicFrog>
And that's resolved with a special case: in a function call, there cannot be a newline between the function and its argument list.
15:19
<@ToxicFrog>
But yes. A statement always begins with a name or (expression), but never continues with a name
15:19
<@ToxicFrog>
And if it continues with an (expression), this is distinguishable with a minor lexer modification.
15:22
<@ToxicFrog>
(to wit: \n( turns into SEMICOLON OPAREN rather than just OPAREN)
15:22
<@ToxicFrog>
...wait, shit, no, that won't work
15:22
<@ToxicFrog>
Because this is legal:
15:22
<@ToxicFrog>
foo(
15:22
<@ToxicFrog>
(2+2)
15:22
<@ToxicFrog>
)
15:22
<@ToxicFrog>
But foo(;(2+2)) isn't.
15:24
<@Vornicus>
You can tell the difference between that and others, though
15:25
<@Vornicus>
You have a state - if you're /expecting/ an infix or postfix operator (of which function calls are postfix) then you can put an implied semicolon.
15:42
<@ToxicFrog>
er?
15:44
<@Vornicus>
There's only one time you can get a function call
15:45
<@Vornicus>
And that's when you're expecting an infix/postfix operator - after names, literals, and parentheses.
15:45
<@Vornicus>
and brackets.
15:46
<@Vornicus>
Thus, if you get to a parentheses after a newline, you only imply a statement break if you're expecting an operator.
15:46
<@Vornicus>
This is the same way you tell the difference between unary minus and subtraction.
15:47
<@Vornicus>
and between grouping and function calls.
15:48
<@Vornicus>
You see what I mean?
15:49
<@ToxicFrog>
Yes. It means making NEWLINE a token, though ;.;
15:50
<@Vornicus>
Such is the cost of not requiring statement terminators.
15:52
<@ToxicFrog>
True.
15:52 * ToxicFrog consults the formal grammar and plays with parser node behaviours
15:53
<@ToxicFrog>
Top-level node is clearly the block node.
15:53
<@ToxicFrog>
Looks ahead 1; on END or $ closes and returns the block, otherwise invokes the statement dispatcher to get another statement AST to pack into the block.
15:54
<@ToxicFrog>
Statement dispatcher dispatches to a bunch of keyword parsers; if given a name, it calls the repetitious statement parser.
15:54
<@ToxicFrog>
(with the name as a starting point)
15:55
<@ToxicFrog>
The RSP looks ahead and dispatches accordingly (statement list, table index, function call, etc).
15:55
<@ToxicFrog>
If statement list, that's the entire statement and it gets returned.
15:55
<@ToxicFrog>
Otherwise, it then calls itself with the newly created AST as a starting point.
15:56
<@ToxicFrog>
If it gets something it can't dispatch on, it either closes and returns the statement (if it has a valid one), or throws a parse error.
15:57
<@ToxicFrog>
Hmm. I think I'll have +{ ... }+ evaluate to a token stream rather than an AST. Easier that way.
16:08 * Vornicus puts together a table of creature stats. Still need druid and archmage damage, the overall combat algorithm, and how exactly the vampire and demon special abilities work.
16:09
<@Vornicus>
(I know how ghosts and trolls work)
16:11
<@Vornicus>
(and dragons)
16:15
<@ToxicFrog>
I think -{ ... }- may have to be handled at the lexer level if I want to keep things simple.
16:15
<@Vornicus>
-{ }-?
16:15
<@ToxicFrog>
Downshift.
16:15
<@Vornicus>
I obviously don't know what you're doing.
16:15
<@ToxicFrog>
Executes the code inside it at compile time, and replaces itself with the token stream or AST that code returns.
16:16
<@Vornicus>
wacky.
16:16
<@Vornicus>
and +{ }+?
16:16
<@ToxicFrog>
Token stream or AST as first order value.
16:16
<@Vornicus>
so kinda like {} in PostScript?
16:16
<@ToxicFrog>
Yes.
16:17
<@ToxicFrog>
Typically, downshifting is used to modify the lexer or parser before the rest of the file is processed.
16:17
<@ToxicFrog>
Installing new keywords and operators, say.
16:18
<@ToxicFrog>
And upshifting is most useful when making those modifications, since you can just write, say, +{ do local e,r = pcall(function() }+ instead of the entire token stream declaration.
16:19
<@ToxicFrog>
Except, using e,r is unsafe (may shadow variables in use by the surrounding code), so you actually go:
16:20
<@ToxicFrog>
+{ do local -{ mksym(),mksym() }- = pcall(function() }+
16:20
<@ToxicFrog>
Where mksym() generates and returns a guaranteed-unique symbol.
16:23
<@ToxicFrog>
What I'm doing here is implementing CTMP for Lua.
16:25
<@Vornicus>
CTMP?
16:25
<@ToxicFrog>
Compile Time Metaprogramming.
16:25
<@ToxicFrog>
A la Lisp macros.
16:25
<@Vornicus>
ah
16:25
<@ToxicFrog>
Lua already has the crazy runtime metaprogramming, but no facilities for changing the shape of the language itself.
16:49
<@ToxicFrog>
Using just -{}- and +{}+ I can kind of implement new stuff - eg, try-catch as -{try}- and -{catch}- - but to add new keywords, I need a parser, so.
16:50 GeekSoldier|work [~Rob@Nightstar-4079.pools.arcor-ip.net] has joined #code
16:50 GeekSoldier|work is now known as GeekSoldier
16:51 * Vornicus ponders. -{}- is kinda like the string-to-executable-code thing in PS.
17:13 You're now known as TheWatcher[afk]
17:28 Forj [~Forj@Nightstar-10789.ue.woosh.co.nz] has joined #code
17:28 mode/#code [+o Forj] by ChanServ
17:28 Chalcedon [~Chalcedon@Nightstar-10789.ue.woosh.co.nz] has joined #code
17:28 mode/#code [+o Chalcedon] by ChanServ
17:44 GeekSoldier [~Rob@Nightstar-4079.pools.arcor-ip.net] has quit [Quit: Praise "BOB"!]
17:46 Syloq [Syloq@Admin.Nightstar.Net] has joined #code
17:47 Syloq is now known as Syloqs-AFH
17:49
<@ToxicFrog>
No, that's loadstring()
17:50
<@ToxicFrog>
-{}- is a downshift; the contents are compiled and executed before the rest of the file is even done being lexed.
17:50 Forj [~Forj@Nightstar-10789.ue.woosh.co.nz] has quit [Quit: Gone]
17:53 Chalcedon [~Chalcedon@Nightstar-10789.ue.woosh.co.nz] has quit [Quit: Gone]
17:55
<@ToxicFrog>
It's not a runtime thing like ps {} or toexec, but has more in common with C's #include
17:55 Syloqs-AFH is now known as Syloq
17:56
<@ToxicFrog>
(and indeed, you can implement #include in terms of downshift)
17:56 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has joined #Code
17:56 mode/#code [+o AnnoDomini] by ChanServ
18:24 GeekSoldier [~Rob@Nightstar-4079.pools.arcor-ip.net] has joined #code
18:39 GeekSoldier [~Rob@Nightstar-4079.pools.arcor-ip.net] has quit [Quit: Praise "BOB"!]
18:39 GeekSoldier [~Rob@Nightstar-4079.pools.arcor-ip.net] has joined #code
18:40 You're now known as TheWatcher
18:49 Syloq is now known as Syloqs-AFH
19:09 * Vornicus fiddles with PyGame. Tries to refamiliarize himself with event models.
19:31 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has quit [Quit: You can't eat someone's pet hamburger!]
19:36 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has joined #Code
19:36 mode/#code [+o AnnoDomini] by ChanServ
19:38 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has quit [Quit: Some people find sanity a little confining.]
19:45 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has joined #Code
19:45 mode/#code [+o AnnoDomini] by ChanServ
19:45 GeekSoldier is now known as GeekSoldier|bed
19:56 GeekSoldier|bed [~Rob@Nightstar-4079.pools.arcor-ip.net] has quit [Ping Timeout]
19:57 GeekSoldier|bed [~Rob@Nightstar-4747.pools.arcor-ip.net] has joined #code
20:00 Vornicus is now known as Vornicus-Latens
20:03 * ToxicFrog constructs what a try-catch implementation would look like once this library is finished
20:44 * gnolam dances his Happy Dance.
20:45
<@gnolam>
Both the I2C communication and the target acquisition actually appears to /work/.
20:50
<@gnolam>
Why I2C was acting up is a complete mystery (I had to change the module's arbitrary address to another arbitrary address to get it to work), but the IR troubles I blame on the specs.
20:50
<@gnolam>
"The specified electro-optical characteristics is satisfied under the following conditions at the controllable distance.
20:50
<@gnolam>
1. Measurement place
20:50
<@gnolam>
A place that is nothing of extreme light reflect in the room.
20:50
<@gnolam>
[...]"
20:52
<@ToxicFrog>
...
20:53
<@gnolam>
Go Taiwan. :P
20:53
<@McMartin>
To take and put the earth wire may cause a large occurrence!
20:57
<@gnolam>
"A place that is nothing of extreme light reflect in the room." => "And the earth was without form, and void; and darkness was upon the face of the deep." ?
20:57
<@McMartin>
My line is, IIRC, "Please do not short things to ground"
20:58
<@McMartin>
Just as yours is, ANAICT, "Do not use laser measurement systems inside rooms full of mirrors."
21:04 * ToxicFrog plays with mixing ASTs and token streams, and also with doing away with ASTs entirely
21:06
<@McMartin>
"AHAHAHAHA!! THEY CALLED ME INSANE! BUT WE'LL SEE WHO'S INSANE ONCE MY ARMY OF KILLER AMOEBAS DESTROYS THIS ENTIRE WORLD!!!" "Yes sir, that should clear things right up."
21:07 AbuDhabi [AnnoDomini@Nightstar-29021.neoplus.adsl.tpnet.pl] has joined #Code
21:07 mode/#code [+o AbuDhabi] by ChanServ
21:08 AnnoDomini [AnnoDomini@Nightstar-29379.neoplus.adsl.tpnet.pl] has quit [Ping Timeout]
21:16
<@ToxicFrog>
...it's not that crazy an idea.
21:17
<@ToxicFrog>
Is it?
21:18
<@gnolam>
It is. A sane person would use dinoflagella.
21:19
<@ToxicFrog>
No, no
21:19
<@ToxicFrog>
The AST/token mix
21:55 * ToxicFrog produces a fuzzy fractal ball using postscript.
21:55
<@ToxicFrog>
That wasn't meant to happen ;.;
22:00 * ToxicFrog tries to figure out how to fill in a single pixel using ps
22:02
<@McMartin>
Doing away with ASTs entirely is kind of madness
22:02
<@McMartin>
However, I would like to direct you to the way Ophis parses arithmetic expressions, because it might end up applying to your expression parser.
22:03
<@McMartin>
... and which I don't have in handy online form, to my irritation.
22:11
<@ToxicFrog>
Well, the thing is, I don't actually need to do the kind of thing I would need ASTs for.
22:12
<@ToxicFrog>
I'm doing a source to source transform; as long as I can verify, modify, and re-emit the token stream, it's good.
22:12
<@ToxicFrog>
...although the way the final data ends up looks kind of like an AST anyways.
22:13
<@ToxicFrog>
It's just an untyped one.
22:15
<@McMartin>
Well, you don't need types
22:15
<@McMartin>
You are likely to need parenthetical grouping though
22:17
<@ToxicFrog>
Well, what happens is, if I give it something like: foo[1](2)
22:18
<@ToxicFrog>
=> ID(foo) [ NUM(1) ] ( NUM(2) )
22:18
<@ToxicFrog>
=> { ID(foo) [ { NUM(1) } ] } { ( NUM(2) }
22:20
<@ToxicFrog>
I think.
22:20
<@ToxicFrog>
The point is, it doesn't turn into named tree nodes, it turns into sequences of mixed tokens and token sequences.
22:22
<@ToxicFrog>
And it also includes tokens that would be discarded in an actual AST; for example, the above would normally be:
22:23
<@ToxicFrog>
functioncall { name = tableindex { name=ID(foo), key=NUM(1) }, args = { NUM(2) } }
22:23
<@ToxicFrog>
Discarding the () and [], since all such information is now part of the tree itself.
22:25
<@McMartin>
Well, the other reason you don't need named tree nodes is that there's really only one node type: "expr".
22:26
<@ToxicFrog>
Actually, expressions and statements are distinct.
22:27
<@ToxicFrog>
But my point is rather that with named nodes, for, say, a function call, you only need to save the tokens (or multi-token trees) making up the function identifer and the arguments, and when generating source from that, you can fill in the punctuation by knowing the node type.
22:27
<@ToxicFrog>
Without that, you need to keep the punctuation.
22:28
<@ToxicFrog>
Since otherwise, I have { ID(foo) NUM(1) } - is that foo[1]? foo(1)?
22:30
<@McMartin>
Ah. Yes.
22:30
<@McMartin>
And token trees are ASTs.
22:31
<@McMartin>
How are you dealing with multiple arguments in function calls
22:31
<@McMartin>
?
22:32
<@ToxicFrog>
argument-list parser, which invokes expression-parser as long as the next token is ',' and packs the resulting trees into a list.
22:32
<@ToxicFrog>
When the next token is ')', closes and returns the list.
22:34
<@ToxicFrog>
(well, actually it's an expression-list parser with a wrapper, but)
22:35
<@McMartin>
That wasn't actually my question
22:35
<@McMartin>
I meant in the AST
22:36
<@ToxicFrog>
Oh. The arguments as a whole are a list (of 0 or more elements), and each element in the list is a list (of 1 or more elements) representing the expression that makes up that argument.
22:45 gnolam is now known as The
22:45 Thaqui [~Thaqui@Nightstar-26276.jetstream.xtra.co.nz] has joined #code
22:45 mode/#code [+o Thaqui] by ChanServ
22:45 The is now known as gnolam
23:04
<@ToxicFrog>
And now I'm back to the fuzzy fractal ball! Argh
23:07
<@ToxicFrog>
...aha. But it's an artifact of the renderer; if I export to PNG, this doesn't happen.
23:07
<@McMartin>
... Oh. Not the parser.
23:07
<@ToxicFrog>
No, fuzzy set theory.
23:07
<@ToxicFrog>
Which is to say homework.
23:08
<@ToxicFrog>
I'd rather be working on the parser, but by friday I need to have a graphical comparison of minmax and product/probsum fuzzy set operations, along with a proof that product intersection implies probsum union.
23:08
<@ToxicFrog>
(and proofs that minmax intersection and union obey DeMorgan's Laws, but I've already done those)
23:13
<@ToxicFrog>
Why were you asking about function arguments?
23:16
<@McMartin>
Because it wasn't clear how they'd be cleanly distinguished in mere token streams
23:19
<@ToxicFrog>
Aah.
23:20
<@ToxicFrog>
Well, since I'm keeping punctuation, you could just look for the COMMA tokens~
23:21
<@ToxicFrog>
At present, post-tree-construction transforms aren't in the design, so once you actually have the tree, all that needs to happen is source generation from it, for which distinguishing isn't very important if you still have the punctuation.
23:21
<@McMartin>
Right
23:22
<@ToxicFrog>
(for example, try/catch - it works by adding a new statement parser, triggered by the try keyword, that invokes the block parser to get the try and catch blocks, then returns a tree containing three new scopes, a function call, and a conditional statement)
23:23
<@ToxicFrog>
(rather than walking the tree afterwards and expanding the try and catch nodes or something)
--- Log closed Wed Nov 28 00:00:11 2007
code logs -> 2007 -> Tue, 27 Nov 2007< code.20071126.log - code.20071128.log >