--- 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 |