{"action":"created","issue":{"url":"https://api.github.com/repos/KSP-KOS/KOS/issues/1034","labels_url":"https://api.github.com/repos/KSP-KOS/KOS/issues/1034/labels{/name}","comments_url":"https://api.github.com/repos/KSP-KOS/KOS/issues/1034/comments","events_url":"https://api.github.com/repos/KSP-KOS/KOS/issues/1034/events","html_url":"https://github.com/KSP-KOS/KOS/issues/1034","id":78273163,"number":1034,"title":"Short-circuit Boolean AND and OR operators.","user":{"login":"Dunbaratu","id":5216848,"avatar_url":"https://avatars.githubusercontent.com/u/5216848?v=3","gravatar_id":"","url":"https://api.github.com/users/Dunbaratu","html_url":"https://github.com/Dunbaratu","followers_url":"https://api.github.com/users/Dunbaratu/followers","following_url":"https://api.github.com/users/Dunbaratu/following{/other_user}","gists_url":"https://api.github.com/users/Dunbaratu/gists{/gist_id}","starred_url":"https://api.github.com/users/Dunbaratu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Dunbaratu/subscriptions","organizations_url":"https://api.github.com/users/Dunbaratu/orgs","repos_url":"https://api.github.com/users/Dunbaratu/repos","events_url":"https://api.github.com/users/Dunbaratu/events{/privacy}","received_events_url":"https://api.github.com/users/Dunbaratu/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/KSP-KOS/KOS/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/KSP-KOS/KOS/labels/kerboscript","name":"kerboscript","color":"eb6420"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":11,"created_at":"2015-05-19T22:22:52Z","updated_at":"2015-05-21T02:49:06Z","closed_at":null,"body":"At the moment, Kerboscript's AND and OR operators don't do short-circuit Booleans.  It was never formally defined whether they do or don't - its just that they coincidentally happen not to.\r\n\r\nThey really should.\r\n\r\n(After this is implemented, then we can revisit old issue #18.)\r\n\r\nThis is my plan of attack:\r\n---------------------------------\r\n\r\n### AND case:\r\n\r\n``expr1 AND expr2`` currently does this:\r\n\r\n- Execute expr1, which pushes its result on the stack.\r\n- Execute expr2, which pushes its result on the stack on top of expr1's result.\r\n- Perform an OpcodeAnd - which pops the top two things and and's them, pushing the Boolean result of the ``and`` on the stack top\r\n\r\nChanging it to short-circuiting means making it do this instead:\r\n\r\n- Execute expr1, which pushes its result on the stack.\r\n- br.false to \"push false\" opcode below.\r\n- Execute expr2, which pushes its result on the stack.\r\n- br.false to \"push false\" opcode below.\r\n- push true // if it got this far, both expressions were true.\r\n- branch to NOP Opcode below. // skip the false case.\r\n- push false [target branched to from the br.false cases above]\r\n- NOP.\r\n\r\n\r\n### OR case:\r\n\r\n``expr1 OR expr2`` currently does this:\r\n\r\n- Execute expr1, which pushes its result on the stack.\r\n- Execute expr2, which pushes its result on the stack on top of expr1's result.\r\n- Perform an OpcodeOr - which pops the top two things and or's them, pushing the Boolean result of the ``or`` on the stack top\r\n\r\nChanging it to short-circuiting means making it do this instead:\r\n\r\n- Execute expr1, which pushes its result on the stack.\r\n- br.true to \"push true\" opcode below. // (br.true doesn't exist yet- may make a new opcode or else do a 'not' followed by a br.false.)\r\n- Execute expr2, which pushes its result on the stack.\r\n- br.true to \"push true\" opcode below. // (br.true doesn't exist yet- may make a new opcode or else do a 'not' followed by a br.false.)\r\n- push false // if it got this far, both expressions were false.\r\n- branch to NOP Opcode below. // skip the true case.\r\n- push true [target branched to from the br.true cases above]\r\n- NOP.\r\n\r\nBREAKING: This makes some simple small boolean expressions take more opcodes to execute, but makes more complex ones take less opcodes to execute.  Increasing number of opcodes executed means breaking some people's trigger code that was nearing the limit, or increasing some people's program sizes.\r\n\r\nThis will have the side effect of rendering OpcodeOr and OpcodeAnd rather useless, as short circuiting accomplishes the same effect by jumping past sections of code rather than by comparing two operands.  It's unclear whether they should remain in the Opcodes.  They probably should for the sake of other future language bindings, or for running KSM direct files, even though I'm nervous about leaving in a feature that doesn't get exercised (and therefore can become incorrect after future changes, without anyone noticing that it broke.)\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/KSP-KOS/KOS/issues/comments/104108408","html_url":"https://github.com/KSP-KOS/KOS/issues/1034#issuecomment-104108408","issue_url":"https://api.github.com/repos/KSP-KOS/KOS/issues/1034","id":104108408,"user":{"login":"Dunbaratu","id":5216848,"avatar_url":"https://avatars.githubusercontent.com/u/5216848?v=3","gravatar_id":"","url":"https://api.github.com/users/Dunbaratu","html_url":"https://github.com/Dunbaratu","followers_url":"https://api.github.com/users/Dunbaratu/followers","following_url":"https://api.github.com/users/Dunbaratu/following{/other_user}","gists_url":"https://api.github.com/users/Dunbaratu/gists{/gist_id}","starred_url":"https://api.github.com/users/Dunbaratu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Dunbaratu/subscriptions","organizations_url":"https://api.github.com/users/Dunbaratu/orgs","repos_url":"https://api.github.com/users/Dunbaratu/repos","events_url":"https://api.github.com/users/Dunbaratu/events{/privacy}","received_events_url":"https://api.github.com/users/Dunbaratu/received_events","type":"User","site_admin":false},"created_at":"2015-05-21T02:49:06Z","updated_at":"2015-05-21T02:49:06Z","body":"Yeah it's impossible to do short-circuiting on ANDs that look like '*' and OR that look like '+'.\r\nHere's why:\r\nThe compiler is late-binding about types.  When you see ``expr1 * expr2`` you won't know what type expr1 is and what type expr2 is until after they've been evaluated.  The entire point of short-circuiting is to avoid evaluating the expression.  So you can't tell if a \"*\" is a boolean-and until after you've already forgone any attempt at short-circuiting, and instead have evaluated the expressions on the left and right sides to discover that they are Booleans.\r\n\r\nSo I'd rather just remove the ability to interepret '*\" as AND and \"+\" as OR.\r\n"}}