IRC Logs for #io Tuesday, 2019-02-05

*** prologic has joined #io13:05
prologicHI jer :D Do you have some time to spare to help me with a compiler/vm bug I'm stuck on?13:06
jerprologic, perhaps14:39
jerjust ask the question, don't expect an immediate response but i'll do my best and respond even if i can't help eventually =]14:39
prologicjer :D thanks :)20:46
prologicSo most bytecode vm compilers emit a TOP or DISCARD opcode at the end of every ExpressionStatement node in the AST. This is fine (mostly) except for one thing20:47
prologicWhen you have a Function with a Body that is a BlockStatement that contains 1 or more ExpressionStatements (same problem with While too) the POP/DIACARD ends up eating up the stack20:48
prologicand you get very undefined behavior (or worse VM crashes)20:48
prologicMy question is this20:48
prologica) When should POP/DISCARD be emitted in general?20:48
jerok so gonna get a little round-about way to hopefully answering this20:53
jerbut when designing any language/vm, consider the core of what you want to build look at everything abstract. pick one thing for your system, two at the most. it might be, for instance, data structures and functions. in this case, you wouldn't have to deal with the while issue, even though it's the same :)20:54
jeranyway that mini rant over20:54
prologichehe20:55
prologicACTION loves Io-ish langs too :D20:55
jera) speaking just in terms of functions, your pop should be emitted after the function returns20:56
jerwhen you say "ends up eating up the stack" what do you mean exactly?20:56
prologicbecuase my impl doesn't do that righ tnow20:56
prologicit POP(s) at the end of every expression block20:56
jerthat seems wasteful20:57
jerthe pops after expressions should be implicit20:57
prologicso a let f = fn() { if (true) { 1}; if (false) { 2} } would emit two POP(s) just after the ifs20:57
prologicand by eat the stack I mean if there are locals on the stack; they get popped off, unintentionally20:58
jerurgh20:58
jerahh20:58
prologicso this is a stupid design :)20:58
jeri'm not a huge fan no =]20:58
prologicI'm trying to understand the rules around a better design of when to emit POP20:58
prologicif this helps to look at code20:59
prologichttps://github.com/prologic/monkey-lang20:59
prologiclook for code.Pop to see what I mean20:59
jerif i were designing a system today, i'd go the route of picking two things to focus on, and implementing the vm in terms of those things, having an orthogonal set of primitives that do things you can't do in the language itself (i.e., if your language has immutable types and supports no immutability, one such thing would be converting one data type to another)20:59
jercan't look at code right now, in a meeting21:00
jer=D21:00
jeri can just ramble21:00
prologicand if it also helps https://gist.github.com/prologic/fbc91c942a5f28a1c1b39e4dfb918da521:01
prologicthis is precisely the wrong behavior I'm seeing21:01
prologicyoull note the evaluator does the right thing ofc :)21:01
prologica tree walker21:01
jerheh sure21:01
prologichah nps21:02
prologichard to find good material on the web on this21:02
jeryou have one single stack or many?21:02
prologicso would one way to "fix" this be to make explicit c.emit(code.Pop) calls?21:02
jeryes21:03
prologicand of a function21:03
prologicwhere else? everywhere else I'm doing this implicitly now?21:03
prologicthis POP is mostly only useful in parts to the REPL ihmo since the REPL prints the vm.LastPoppedValue()21:04
jeryeah this is where my other question was leading -- if you're dealing with one stack, you can simply take the last value on the stack (your return value from your function), store it temporarily, go back to the point in the stack you intended to be at, and push that onto the stack, implicitly21:04
prologic[07:02:51]  <jer>you have one single stack or many? <-- singel stack21:04
prologicand yeah stack based vm21:04
jerstack based vms are evil =D21:04
jeri hate them21:05
jerhehe21:05
jerunless you're building a concatenative language, then they're ideal21:05
jerin this way, for instance, just to go down a rabbit hole because it's interesting21:06
jerif you designed a stack based vm that was based on the idea of multiple stacks -- where each function took an implicit stack as an argument and returned one21:06
prologicso you put the return value away temporarily somewhere just for the REPL to access?21:06
prologicso it can be printed?21:06
jerthat'd produce a highly composable system 21:06
jerprologic, no i put it somewhere, clean up the stack my function was manipualting, and then once i've reset the stack pointer to the place on the stack where the call to the function was made, push the value i wanted to return onto the stack21:07
prologicoh21:08
prologicmy RETURN opcode does this21:08
jerok21:08
jerso this problem is PURELY to solve the repl?21:08
prologicno21:08
jerthen i'm confused21:08
prologicif you have multiple expression statements in a block, there are too many pops and the stack is eaten up21:09
prologicI loose locals (which are on the stack, etc)21:09
prologicusing stack hold to store locals21:09
jerwhy are you popping if you're not pushing the values of the expression onto the stack?21:10
prologicperhaps this helps21:11
prologic     0014 Equal21:11
prologic     0015 JumpIfFalse 2621:11
prologic     0018 LoadConstant 221:11
prologic     0021 AssignLocal 221:11
prologic     0023 Jump 2721:11
prologic     0026 LoadNull21:11
prologic     0027 Pop21:11
prologicthis is a bit of bytecode emitted21:12
prologicfor:21:12
prologic  if (s[0] == c) {21:12
prologic    x = 021:12
prologic  }21:12
prologicI think you're on to something though21:12
prologicthe Jump 27 here if the condition is met; AssignLocal leave nothing on the stack (I don' thtink)21:13
prologicso the Pop pops something it's not meant to?21:13
prologicahh yes AssignLocal pops the top most value off the stack and stores it in the locals slot in the stack hold I create for functions21:14
prologicAnd now the Pop on 00027 is wrong21:14
prologictoo many of these and it eats my stack hold of locals :)21:14
jerbingo21:14
jerso pushes and pops aren't always explicit as i'm sure is now clear to you =]21:15
prologicyeah21:15
jeri've found writing docs about what my opcodes do helpful in these cases, also largely annoying21:15
jerit's why i prefer explicit datapath machines now21:15
jercomputation is a side effect of moving data from one bucket to another21:15
prologicfair21:16
prologicthis has been helpful thank you :)21:16
jerno worries =]21:16
prologicI must get to work/etc but have a lovely evenin'n :)21:16
jeryou too21:16
prologicmorning but *meh* :)21:16
jeri'm -0600 UTC so evening for me21:23
jertechnically still afternoon21:23

Generated by irclog2html.py 2.14.0 by Marius Gedminas - find it at mg.pov.lt!