Advertisement
lauriszz123

ComputerCraft BASIC

Dec 4th, 2017
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 71.74 KB | None | 0 0
  1. --------INIT--------
  2. local tArgs = { ... }
  3. _w, _h = term.getSize()
  4. _BAS_VER = "6"
  5. if fs.exists( "hiresAPI" ) == false then
  6.     shell.run( "pastebin", "get", "TFFJwxvp", "hiresAPI" )
  7.     os.loadAPI( "hiresAPI" )
  8.     print( "Using oli414's Canvas API" )
  9.     sleep( 3 )
  10. else
  11.     os.loadAPI( "hiresAPI" )
  12. end
  13. canvas = {}
  14.  
  15. --***COMPLETE COPY OF CC READ FUNCTION***--
  16. local function _read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
  17.     if _sReplaceChar ~= nil and type( _sReplaceChar ) ~= "string" then
  18.         error( "bad argument #1 (expected string, got " .. type( _sReplaceChar ) .. ")", 2 )
  19.     end
  20.     if _tHistory ~= nil and type( _tHistory ) ~= "table" then
  21.         error( "bad argument #2 (expected table, got " .. type( _tHistory ) .. ")", 2 )
  22.     end
  23.     if _fnComplete ~= nil and type( _fnComplete ) ~= "function" then
  24.         error( "bad argument #3 (expected function, got " .. type( _fnComplete ) .. ")", 2 )
  25.     end
  26.     if _sDefault ~= nil and type( _sDefault ) ~= "string" then
  27.         error( "bad argument #4 (expected string, got " .. type( _sDefault ) .. ")", 2 )
  28.     end
  29.     term.setCursorBlink( true )
  30.  
  31.     local sLine
  32.     if type( _sDefault ) == "string" then
  33.         sLine = _sDefault
  34.     else
  35.         sLine = ""
  36.     end
  37.     local nHistoryPos
  38.     local nPos = #sLine
  39.     if _sReplaceChar then
  40.         _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  41.     end
  42.  
  43.     local tCompletions
  44.     local nCompletion
  45.     local function recomplete()
  46.         if _fnComplete and nPos == string.len(sLine) then
  47.             tCompletions = _fnComplete( sLine )
  48.             if tCompletions and #tCompletions > 0 then
  49.                 nCompletion = 1
  50.             else
  51.                 nCompletion = nil
  52.             end
  53.         else
  54.             tCompletions = nil
  55.             nCompletion = nil
  56.         end
  57.     end
  58.  
  59.     local function uncomplete()
  60.         tCompletions = nil
  61.         nCompletion = nil
  62.     end
  63.  
  64.     local w = term.getSize()
  65.     local sx = term.getCursorPos()
  66.  
  67.     local function redraw( _bClear )
  68.         local nScroll = 0
  69.         if sx + nPos >= w then
  70.             nScroll = (sx + nPos) - w
  71.         end
  72.  
  73.         local cx,cy = term.getCursorPos()
  74.         term.setCursorPos( sx, cy )
  75.         local sReplace = (_bClear and " ") or _sReplaceChar
  76.         if sReplace then
  77.             term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )
  78.         else
  79.             term.write( string.sub( sLine, nScroll + 1 ) )
  80.         end
  81.  
  82.         if nCompletion then
  83.             local sCompletion = tCompletions[ nCompletion ]
  84.             local oldText, oldBg
  85.             if not _bClear then
  86.                 oldText = term.getTextColor()
  87.                 oldBg = term.getBackgroundColor()
  88.                 term.setTextColor( colors.white )
  89.                 term.setBackgroundColor( colors.gray )
  90.             end
  91.             if sReplace then
  92.                 term.write( string.rep( sReplace, string.len( sCompletion ) ) )
  93.             else
  94.                 term.write( sCompletion )
  95.             end
  96.             if not _bClear then
  97.                 term.setTextColor( oldText )
  98.                 term.setBackgroundColor( oldBg )
  99.             end
  100.         end
  101.  
  102.         term.setCursorPos( sx + nPos - nScroll, cy )
  103.     end
  104.    
  105.     local function clear()
  106.         redraw( true )
  107.     end
  108.  
  109.     recomplete()
  110.     redraw()
  111.  
  112.     local function acceptCompletion()
  113.         if nCompletion then
  114.             -- Clear
  115.             clear()
  116.  
  117.             -- Find the common prefix of all the other suggestions which start with the same letter as the current one
  118.             local sCompletion = tCompletions[ nCompletion ]
  119.             sLine = sLine .. sCompletion
  120.             nPos = string.len( sLine )
  121.  
  122.             -- Redraw
  123.             recomplete()
  124.             redraw()
  125.         end
  126.     end
  127.     while true do
  128.         local sEvent, param = os.pullEventRaw()
  129.         if sEvent == "terminate" then
  130.             return 0xE7D
  131.         elseif sEvent == "char" then
  132.             -- Typed key
  133.             clear()
  134.             sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  135.             nPos = nPos + 1
  136.             recomplete()
  137.             redraw()
  138.  
  139.         elseif sEvent == "paste" then
  140.             -- Pasted text
  141.             clear()
  142.             sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  143.             nPos = nPos + string.len( param )
  144.             recomplete()
  145.             redraw()
  146.  
  147.         elseif sEvent == "key" then
  148.             if param == keys.enter then
  149.                 -- Enter
  150.                 if nCompletion then
  151.                     clear()
  152.                     uncomplete()
  153.                     redraw()
  154.                 end
  155.                 break
  156.                
  157.             elseif param == keys.left then
  158.                 -- Left
  159.                 if nPos > 0 then
  160.                     clear()
  161.                     nPos = nPos - 1
  162.                     recomplete()
  163.                     redraw()
  164.                 end
  165.                
  166.             elseif param == keys.right then
  167.                 -- Right                
  168.                 if nPos < string.len(sLine) then
  169.                     -- Move right
  170.                     clear()
  171.                     nPos = nPos + 1
  172.                     recomplete()
  173.                     redraw()
  174.                 else
  175.                     -- Accept autocomplete
  176.                     acceptCompletion()
  177.                 end
  178.  
  179.             elseif param == keys.up or param == keys.down then
  180.                 -- Up or down
  181.                 if nCompletion then
  182.                     -- Cycle completions
  183.                     clear()
  184.                     if param == keys.up then
  185.                         nCompletion = nCompletion - 1
  186.                         if nCompletion < 1 then
  187.                             nCompletion = #tCompletions
  188.                         end
  189.                     elseif param == keys.down then
  190.                         nCompletion = nCompletion + 1
  191.                         if nCompletion > #tCompletions then
  192.                             nCompletion = 1
  193.                         end
  194.                     end
  195.                     redraw()
  196.  
  197.                 elseif _tHistory then
  198.                     -- Cycle history
  199.                     clear()
  200.                     if param == keys.up then
  201.                         -- Up
  202.                         if nHistoryPos == nil then
  203.                             if #_tHistory > 0 then
  204.                                 nHistoryPos = #_tHistory
  205.                             end
  206.                         elseif nHistoryPos > 1 then
  207.                             nHistoryPos = nHistoryPos - 1
  208.                         end
  209.                     else
  210.                         -- Down
  211.                         if nHistoryPos == #_tHistory then
  212.                             nHistoryPos = nil
  213.                         elseif nHistoryPos ~= nil then
  214.                             nHistoryPos = nHistoryPos + 1
  215.                         end                        
  216.                     end
  217.                     if nHistoryPos then
  218.                         sLine = _tHistory[nHistoryPos]
  219.                         nPos = string.len( sLine )
  220.                     else
  221.                         sLine = ""
  222.                         nPos = 0
  223.                     end
  224.                     uncomplete()
  225.                     redraw()
  226.  
  227.                 end
  228.  
  229.             elseif param == keys.backspace then
  230.                 -- Backspace
  231.                 if nPos > 0 then
  232.                     clear()
  233.                     sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  234.                     nPos = nPos - 1
  235.                     recomplete()
  236.                     redraw()
  237.                 end
  238.  
  239.             elseif param == keys.home then
  240.                 -- Home
  241.                 if nPos > 0 then
  242.                     clear()
  243.                     nPos = 0
  244.                     recomplete()
  245.                     redraw()
  246.                 end
  247.  
  248.             elseif param == keys.delete then
  249.                 -- Delete
  250.                 if nPos < string.len(sLine) then
  251.                     clear()
  252.                     sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )                
  253.                     recomplete()
  254.                     redraw()
  255.                 end
  256.  
  257.             elseif param == keys["end"] then
  258.                 -- End
  259.                 if nPos < string.len(sLine ) then
  260.                     clear()
  261.                     nPos = string.len(sLine)
  262.                     recomplete()
  263.                     redraw()
  264.                 end
  265.  
  266.             elseif param == keys.tab then
  267.                 -- Tab (accept autocomplete)
  268.                 acceptCompletion()
  269.  
  270.             end
  271.  
  272.         elseif sEvent == "term_resize" then
  273.             -- Terminal resized
  274.             w = term.getSize()
  275.             redraw()
  276.  
  277.         end
  278.     end
  279.  
  280.     local cx, cy = term.getCursorPos()
  281.     term.setCursorBlink( false )
  282.     term.setCursorPos( w + 1, cy )
  283.     print()
  284.    
  285.     return sLine
  286. end
  287.  
  288. local COLO = {
  289.     [ 0x0 ] = 0x0001;
  290.     [ 0x1 ] = 0x0002;
  291.     [ 0x2 ] = 0x0004;
  292.     [ 0x3 ] = 0x0008;
  293.     [ 0x4 ] = 0x0010;
  294.     [ 0x5 ] = 0x0020;
  295.     [ 0x6 ] = 0x0040;
  296.     [ 0x7 ] = 0x0080;
  297.     [ 0x8 ] = 0x0100;
  298.     [ 0x9 ] = 0x0200;
  299.     [ 0xA ] = 0x0400;
  300.     [ 0xB ] = 0x0800;
  301.     [ 0xC ] = 0x1000;
  302.     [ 0xD ] = 0x2000;
  303.     [ 0xE ] = 0x4000;
  304.     [ 0xF ] = 0x8000;
  305. }
  306.  
  307. --------Bytecode--------
  308. local BC_HALT = 0x00
  309. local BC_GOSUB = 0x01
  310. local BC_ADD = 0x02
  311. local BC_SUB = 0x03
  312. local BC_VSET = 0x04
  313. local BC_VGET = 0x05
  314. local BC_ARGS = 0x06
  315. local BC_MUL = 0x07
  316. local BC_DIV = 0x08
  317. local BC_PUSH = 0x09
  318. local BC_POP = 0x0A
  319. local BC_CALL = 0x0B
  320. local BC_JUMP = 0x0C
  321. local BC_RET = 0x0D
  322. local BC_VFREE = 0x0E
  323. local BC_VDEF = 0x0F
  324. local BC_MOD = 0x10
  325. local BC_POW = 0x11
  326. local BC_CMP = 0x12
  327. local BC_JPC = 0x13
  328. local BC_STORE = 0x14
  329. local BC_LOAD = 0x15
  330. local BC_DUP = 0x16
  331. local BC_CARR = 0x17
  332. local BC_AND = 0x18
  333. local BC_OR = 0x19
  334. local BC_EXPECT = 0x20
  335.  
  336. local opToName = {
  337.     [ BC_HALT ] = { "HALT", 0 };
  338.     [ BC_GOSUB ] = { "GOSUB", 0 };
  339.     [ BC_ADD ] = { "ADD", 0 };
  340.     [ BC_SUB ] = { "SUB", 0 };
  341.     [ BC_VSET ] = { "VARSET", 1 };
  342.     [ BC_VGET ] = { "VARGET", 1 };
  343.     [ BC_ARGS ] = { "ARGS", 1 };
  344.     [ BC_MUL ] = { "MUL", 0 };
  345.     [ BC_DIV ] = { "DIV", 0 };
  346.     [ BC_PUSH ] = { "PUSH", 1 };
  347.     [ BC_POP ] = { "POP", 0 };
  348.     [ BC_CALL ] = { "CALL", 1 };
  349.     [ BC_JUMP ] = { "JUMP", 1 };
  350.     [ BC_RET ] = { "RETURN", 0 };
  351.     [ BC_VFREE ] = { "VARFREE", 1 };
  352.     [ BC_VDEF ] = { "VARDEF", 1 };
  353.     [ BC_MOD ] = { "MOD", 0 };
  354.     [ BC_POW ] = { "POW", 0 };
  355.     [ BC_CMP ] = { "COMPARE", 1 };
  356.     [ BC_JPC ] = { "CONDJMP", 2 };
  357.     [ BC_STORE ] = { "STORE", 1 };
  358.     [ BC_LOAD ] = { "LOAD", 1 };
  359.     [ BC_DUP ] = { "DUP", 0 };
  360.     [ BC_AND ] =  { "AND", 0 };
  361.     [ BC_OR ] = { "OR", 0 };
  362.     [ BC_CARR ] = { "REATEARRAY", 0 };
  363.     [ BC_EXPECT ] = { "EXPECT", 1 };
  364. }
  365.  
  366. local buttons = {
  367.     0, --LEFT
  368.     0, --RIGHT
  369.     0, --UP
  370.     0, --DOWN
  371.     0, --Z
  372.     0  --X
  373. }
  374. local allEvInputs = {}
  375.  
  376. --------Interpreter--------
  377. local _PROGRAM_OFFSET = 1
  378. local memory = {}
  379. local stack = {}
  380. local jstack = {}
  381. local PC = 1
  382. local SP = 0
  383. local jSP = 0
  384. local isRunning = true
  385. EVENTS = {}
  386.  
  387. --------Stack management--------
  388. local function spush( v )
  389.     SP = SP + 1
  390.     stack[ SP ] = v
  391. end
  392. local function rpush( v )
  393.     jSP = jSP + 1
  394.     jstack[ jSP ] = v
  395. end
  396. local function spop()
  397.     if SP < 0 then
  398.         printError( "BASIC: stack underflow" )
  399.         printError( "PC: "..PC )
  400.         isRunning = false
  401.         return 0
  402.     end
  403.     local v = stack[ SP ]
  404.     stack[ SP ] = nil
  405.     SP = SP - 1
  406.     return v
  407. end
  408. local function rpop()
  409.     if jSP < 0 then
  410.         printError( "BASIC: stack underflow" )
  411.         printError( "PC: "..PC )
  412.         isRunning = false
  413.         return 0
  414.     end
  415.     local v = jstack[ jSP ]
  416.     jstack[ jSP ] = nil
  417.     jSP = jSP - 1
  418.     return v
  419. end
  420.  
  421. --------INPUT--------
  422. local currLine = 1
  423. local lineOffset = 1
  424. local currFile = ""
  425.  
  426. local function inputFile( str )
  427.     str=str.."\n"
  428.     local p = 1
  429.     currLine = 1
  430.     lineOffset = 1
  431.     return {
  432.         [ "next" ] = function()
  433.             local v = str:sub( p, p )
  434.             lineOffset = lineOffset + 1
  435.             if v == "\n" then
  436.                 currLine = currLine + 1
  437.                 lineOffset = 1
  438.             end
  439.             p = p + 1
  440.             return v
  441.         end;
  442.         [ "peek" ] = function()
  443.             return str:sub( p, p )
  444.         end;
  445.         [ "eof" ] = function()
  446.             return p > #str
  447.         end;
  448.         [ "error" ] = function( msg )
  449.             msg = msg or ""
  450.             error( currFile..": "..currLine..", "..lineOffset.." -> "..msg, 0 )
  451.         end;
  452.     }
  453. end
  454.  
  455. --------TOKENIZER--------
  456. local function tokenize( input )
  457.     local function isNum( c )
  458.         return c:match( "[0-9]" ) ~= nil
  459.     end
  460.     local function isChr( c )
  461.         return c:match( "[_a-zA-Z]" ) ~= nil
  462.     end
  463.     local function isOp( c )
  464.         return c:match( "[<=>%+%-/%*^%%]" ) ~= nil
  465.     end
  466.     local function isPunc( c )
  467.         return c:match( "[.,%(%);:]" ) ~= nil
  468.     end
  469.     local function isWht( c )
  470.         return c:match( "[ \t]" ) ~= nil
  471.     end
  472.  
  473.     local function rw( p )
  474.         local str = ""
  475.         while input.eof() == false and p( input.peek() ) do
  476.             str = str .. input.next()
  477.         end
  478.         return str
  479.     end
  480.     local function rws( p )
  481.         local str = ""
  482.         while input.eof() == false and p( input.peek() ) do
  483.             if input.peek() == "\\" then
  484.                 input.next()
  485.                 str = str .. input.next()
  486.             else
  487.                 str = str .. input.next()
  488.             end
  489.         end
  490.         return str
  491.     end
  492.  
  493.     local function rchr()
  494.         return {
  495.             [ "type" ] = "id";
  496.             [ "value" ] = rw( isChr );
  497.         }
  498.     end
  499.     local function rnum()
  500.         local f = rw( isNum )
  501.         if input.peek() == "." then
  502.             input.next()
  503.             if #f == 0 then
  504.                 f = "0"
  505.             end
  506.             f = f .."."..rw( isNum )
  507.         end
  508.         return {
  509.             [ "type" ] = "num";
  510.             [ "value" ] = f;
  511.         }
  512.     end
  513.     local function rops()
  514.         return {
  515.             [ "type" ] = "op";
  516.             [ "value" ] = rw( isOp );
  517.         }
  518.     end
  519.     local function rpunc()
  520.         return {
  521.             [ "type" ] = "punc";
  522.             [ "value" ] = input.next();
  523.         }
  524.     end
  525.     local function rstring( p )
  526.         input.next()
  527.         local str = rws( function( p )
  528.             return p ~= "\""
  529.         end )
  530.         if input.next() ~= p then
  531.             input.error( "string not closed" )
  532.         end
  533.         return {
  534.             [ "type" ] = "str";
  535.             [ "value" ] = str;
  536.         }
  537.     end
  538.  
  539.     local function rnext()
  540.         rw( isWht )
  541.         if input.eof() == false then
  542.             local p = input.peek()
  543.             if p == "\n" then
  544.                 rw( function( c )
  545.                     return c == "\n"
  546.                 end )
  547.                 return {
  548.                     [ "type" ] = "newline";
  549.                 }
  550.             elseif p == "\"" then
  551.                 return rstring( p )
  552.             elseif isNum( p ) then
  553.                 return rnum()
  554.             elseif p == "." then
  555.                 return rnum()
  556.             elseif isChr( p ) then
  557.                 return rchr()
  558.             elseif isOp( p ) then
  559.                 return rops()
  560.             elseif isPunc( p ) then
  561.                 return rpunc()
  562.             else
  563.                 input.next()
  564.                 return {
  565.                     [ "type" ] = "undef";
  566.                 }
  567.             end
  568.         else
  569.             return {
  570.                 [ "type" ] = "EOF";
  571.             }
  572.         end
  573.     end
  574.  
  575.     local curr
  576.     return {
  577.         [ "next" ] = function()
  578.             local c = curr
  579.             curr = nil
  580.             return c or rnext()
  581.         end;
  582.         [ "peek" ] = function()
  583.             if curr then return curr else
  584.                 curr = rnext()
  585.                 return curr
  586.             end
  587.         end;
  588.         [ "eof" ] = input.eof;
  589.         [ "error" ] = input.error;
  590.     }
  591. end
  592.  
  593. local PRECEDENCE = {
  594.     [ "or" ] = 1,
  595.     [ "and" ] = 2,
  596.     [ "<" ] = 3, [ ">" ] = 3, [ "<=" ] = 3, [ ">=" ] = 3, [ "=" ] = 3, [ "<>" ] = 3,
  597.     [ "+" ] = 4, [ "-" ] = 4,
  598.     [ "*" ] = 5, [ "/" ] = 5, [ "%" ] = 5, [ "^" ] = 5
  599. };
  600.  
  601. --------PARSER--------
  602. --------PARSER--------
  603. local function parse( input )
  604.     local function expect( t, v, l )
  605.         local i = input.next()
  606.         if i.type == t then
  607.             if v then
  608.                 if l == true then
  609.                     i.value = i.value:lower()
  610.                 end
  611.                 if v == i.value then
  612.                     return true
  613.                 else
  614.                     input.error( "expected value <"..v.."> got <"..i.value..">" )
  615.                 end
  616.             else
  617.                 return i.value
  618.             end
  619.         else
  620.             input.error( "expected type <"..t.."> got <"..i.type..">" )
  621.         end
  622.     end
  623.  
  624.     --Binary parsing
  625.     local function atom()
  626.         if input.peek().type == "num" then
  627.             return input.next()
  628.         elseif input.peek().type == "str" then
  629.             return input.next()
  630.         elseif input.peek().type == "id" then
  631.             local v = input.next()
  632.             if input.peek().value == "(" then
  633.                 return ecall( v.value )
  634.             else
  635.                 return {
  636.                     [ "type" ] = "var_get";
  637.                     [ "name" ] = v.value;
  638.                 }
  639.             end
  640.         elseif input.peek().value == "(" then
  641.             expect( "punc", "(" )
  642.             local v = binary()
  643.             expect( "punc", ")" )
  644.             return v
  645.         else
  646.             input.error( "expected a value got "..input.peek().value )
  647.         end
  648.     end
  649.     function binary( left, myPrc )
  650.         local myPrc = myPrc or 0
  651.         local left = left or atom()
  652.         if input.peek().value == "and" or input.peek().value == "or" or input.peek().type == "op" then
  653.             local prc = PRECEDENCE[ input.peek().value ]
  654.             if prc > myPrc then
  655.                 local bin = {
  656.                     [ "type" ] = "binary";
  657.                     [ "op" ] = input.next().value;
  658.                     [ "left" ] = left;
  659.                     [ "right" ] = binary( atom(), prc );
  660.                 }
  661.                 return binary( bin, myPrc )
  662.             end
  663.         end
  664.         return left
  665.     end
  666.  
  667.     --Variable parsing
  668.     local function vardef()
  669.         expect( "id", "let", true )
  670.         local name = expect( "id" )
  671.         if input.peek().type == "op" then
  672.             expect( "op", "=" )
  673.             return {
  674.                 [ "type" ] = "var_defset";
  675.                 [ "name" ] = name;
  676.                 [ "value" ] = binary();
  677.             }
  678.         else
  679.             return {
  680.                 [ "type" ] = "var_def";
  681.                 [ "name" ] = name;
  682.             }
  683.         end
  684.     end
  685.     local lineIndex = false
  686.     local function varset( name )
  687.         expect( "op", "=" )
  688.         return {
  689.             [ "type" ] = "var_set";
  690.             [ "name" ] = name;
  691.             [ "value" ] = binary();
  692.         }
  693.     end
  694.     local function parseif()
  695.         expect( "id", "if", true )
  696.         local cond = binary()
  697.         expect( "id", "then", true )
  698.         return {
  699.             [ "type" ] = "if";
  700.             [ "cond" ] = cond;
  701.             [ "then" ] = statement();
  702.         }
  703.     end
  704.     local function parsedef()
  705.         expect( "id", "def", true )
  706.         local name = expect( "id" )
  707.         expect( "punc", "(" )
  708.         local vararg = {}
  709.         while input.eof() == false do
  710.             if input.peek().type == "id" then
  711.                 vararg[ #vararg + 1 ] = input.next().value
  712.             elseif input.peek().value == "," then
  713.                 input.next()
  714.             else
  715.                 break
  716.             end
  717.         end
  718.         expect( "punc", ")" )
  719.         expect( "op", "=" )
  720.         local value
  721.         if input.peek().value == "if" then
  722.             value = parseif()
  723.         else
  724.             local l = atom()
  725.             if input.peek().value == "=" then
  726.                 value = varset( l.name )
  727.             else
  728.                 value = binary( l )
  729.             end
  730.         end
  731.         return {
  732.             [ "type" ] = "defun";
  733.             [ "name" ] = name;
  734.             [ "vararg" ] = vararg;
  735.             [ "value" ] = value;
  736.         }
  737.     end
  738.  
  739.     local function parserem()
  740.         expect( "id", "rem", true )
  741.         while input.eof() == false do
  742.             if input.peek().type == "newline" then
  743.                 break
  744.             else
  745.                 input.next()
  746.             end
  747.         end
  748.         expect( "newline" )
  749.     end
  750.  
  751.     local function parsefor()
  752.         expect( "id", "for", true )
  753.         local vname = expect( "id" )
  754.         expect( "op", "=" )
  755.         local value = binary()
  756.         expect( "id", "to", true )
  757.         local to = binary()
  758.         local step
  759.         if input.peek().value == "step" then
  760.             expect( "id", "step", true )
  761.             step = binary()
  762.             if input.peek().type == "newline" then
  763.                 input.next()
  764.             end
  765.         end
  766.         local prog = {}
  767.         local foundNext = false
  768.         while input.eof() == false do
  769.             local l = line()
  770.             if type( l ) == "table" then
  771.                 prog[ #prog + 1 ] = l
  772.             else
  773.                 foundNext = true
  774.                 break
  775.             end
  776.         end
  777.         if foundNext == false then
  778.             input.error( "for loop expected closing keyword 'next'" )
  779.         end
  780.         return {
  781.             [ "type" ] = "loop";
  782.             [ "var" ] = vname;
  783.             [ "value" ] = value;
  784.             [ "stepto" ] = to;
  785.             [ "step" ] = step;
  786.             [ "prog" ] = prog;
  787.         }
  788.     end
  789.  
  790.     --Function call parsing ( in LINE )
  791.     local function lcargs()
  792.         local args = {}
  793.         if input.peek().type == "newline" then
  794.             input.next()
  795.             return args
  796.         end
  797.         while input.eof() == false do
  798.             args[ #args + 1 ] = binary()
  799.             if input.peek().value == "," then
  800.                 input.next()
  801.             else
  802.                 if input.peek().value == "\n" then
  803.                     input.next()
  804.                 end
  805.                 break
  806.             end
  807.         end
  808.         return args
  809.     end
  810.     local function lcall( name )
  811.         return {
  812.             [ "type" ] = "call";
  813.             [ "name" ] = name:lower();
  814.             [ "args" ] = lcargs();
  815.         }
  816.     end
  817.  
  818.     --Function call parsing ( in EXPRESSION )
  819.     local function ecargs()
  820.         expect( "punc", "(" )
  821.         local args = {}
  822.         while input.eof() == false do
  823.             if input.peek().value == ")" then
  824.                 break
  825.             end
  826.             args[ #args + 1 ] = binary()
  827.             if input.peek().value == "," then
  828.                 input.next()
  829.             else
  830.                 if input.peek().value == "\n" then
  831.                     input.next()
  832.                 end
  833.                 break
  834.             end
  835.         end
  836.         expect( "punc", ")" )
  837.         return args
  838.     end
  839.     function ecall( name )
  840.         return {
  841.             [ "type" ] = "call";
  842.             [ "name" ] = name:lower();
  843.             [ "args" ] = ecargs();
  844.         }
  845.     end
  846.  
  847.     function statement( use_label )
  848.         local p = input.peek()
  849.         if p.value:lower() == "goto" then
  850.             input.next()
  851.             return {
  852.                 [ "type" ] = "goto";
  853.                 [ "value" ] = input.next().value;
  854.             }
  855.         elseif p.value:lower() == "gosub" then
  856.             input.next()
  857.             return {
  858.                 [ "type" ] = "gosub";
  859.                 [ "value" ] = binary();
  860.             }
  861.         elseif p.value:lower() == "return" then
  862.             input.next()
  863.             return { [ "type" ] = "return"; }
  864.         elseif p.type == "id" then
  865.             local v = input.next().value
  866.             if input.peek().value == "=" then
  867.                 return varset( v )
  868.             elseif input.peek().value == ":" then
  869.                 if use_label == true then
  870.                     input.next()
  871.                     return {
  872.                         [ "type" ] = "label";
  873.                         [ "name" ] = v;
  874.                     }
  875.                 else
  876.                     input.error( "can't define that label :( try it outside of 'if' :)" )
  877.                 end
  878.             else
  879.                 return lcall( v )
  880.             end
  881.         else
  882.             return binary()
  883.         end
  884.     end
  885.  
  886.     function line()
  887.         if input.eof() == false and input.peek().type ~= "EOF" then
  888.             if input.peek().type == "newline" then
  889.                 input.next()
  890.             end
  891.             local value, line
  892.             if lineIndex == true then
  893.                 line = expect( "num" )
  894.             end
  895.             local p = input.peek()
  896.             if p.value:lower() == "rem" then
  897.                 return parserem()
  898.             elseif p.value:lower() == "def" then
  899.                 value = parsedef()
  900.             elseif p.value:lower() == "let" then
  901.                 value = vardef()
  902.             elseif p.value:lower() == "data" then
  903.                 input.next()
  904.                 value = {
  905.                     [ "type" ] = "array";
  906.                     [ "name" ] = expect( "id" );
  907.                 }
  908.             elseif p.value:lower() == "if" then
  909.                 value = parseif()
  910.             elseif p.value:lower() == "for" then
  911.                 value = parsefor()
  912.             elseif p.value:lower() == "next" then
  913.                 input.next()
  914.                 if input.peek().type == "newline" then
  915.                     input.next()
  916.                 end
  917.                 return true
  918.             else
  919.                 local v = {}
  920.                 while true do
  921.                     v[ #v + 1 ] = statement( true )
  922.                     if input.peek().value == ":" then
  923.                         input.next()
  924.                     else
  925.                         break
  926.                     end
  927.                 end
  928.                 value = v
  929.             end
  930.             if input.peek().type == "newline" then
  931.                 input.next()
  932.             end
  933.             return {
  934.                 [ "type" ] = "line";
  935.                 [ "line" ] = line or currLine;
  936.                 [ "value" ] = value;
  937.             }
  938.         end
  939.     end
  940.  
  941.     local function program()
  942.         local prog = {}
  943.         if input.peek().type == "num" then
  944.             lineIndex = true
  945.         end
  946.         while input.eof() == false do
  947.             prog[ #prog + 1 ] = line()
  948.             if input.peek().type == "newline" then
  949.                 input.next()
  950.             end
  951.         end
  952.         return {
  953.             [ "type" ] = "program";
  954.             [ "prog" ] = prog;
  955.         }
  956.     end
  957.  
  958.     return program()
  959. end
  960.  
  961. --------COMPILER--------
  962. local pc = 1
  963. local pcs = {}
  964. local currMem
  965. local function addToMem( ... )
  966.     local v = { ... }
  967.     for i=1, #v do
  968.         currMem[ #currMem + 1 ] = v[ i ]
  969.         pc = pc + 1
  970.     end
  971. end
  972. local function addToMem2( ... )
  973.     local v = { ... }
  974.     for i=1, #v do
  975.         currMem[ #currMem + 1 ] = v[ i ]
  976.     end
  977. end
  978. local function preProcMem( ... )
  979.     local v = { ... }
  980.     for i=1, #v do
  981.         pc = pc + 1
  982.     end
  983. end
  984. local cifcount = 0
  985. local function preProcBin( op )
  986.     if op == "=" or op == "<" or op == ">" or
  987.     op == "<>" or op == ">=" or op == "<=" then
  988.         preProcMem( 0, 1 )
  989.     else
  990.         preProcMem( 0 )
  991.     end
  992. end
  993. local eop = 0
  994. local forloopc = 0
  995. local defuncs = {}
  996. local function preProcLabels( v )
  997.     if v.type == "program" then
  998.         for i=1, #v.prog do
  999.             preProcLabels( v.prog[ i ] )
  1000.         end
  1001.         return
  1002.     elseif v.type == "line" then
  1003.         if #v.value > 0 then
  1004.             for i=1, #v.value do
  1005.                 preProcLabels( v.value[ i ] )
  1006.             end
  1007.         else
  1008.             preProcLabels( v.value )
  1009.         end
  1010.     elseif v.type == "label" then
  1011.         preProcMem( BC_VDEF, 1 )
  1012.         preProcMem( BC_PUSH, 1 )
  1013.         preProcMem( BC_VSET, 1 )
  1014.     elseif v.type == "defun" then
  1015.         defuncs[ v.name ] = true
  1016.         preProcMem( BC_VDEF, 1 )
  1017.         preProcMem( BC_PUSH, 1 )
  1018.         preProcMem( BC_VSET, 1 )
  1019.     elseif v.type == "loop" then
  1020.         for i=1, #v.prog do
  1021.             preProcLabels( v.prog[ i ] )
  1022.         end
  1023.     end
  1024. end
  1025. local function preProc( v, env )
  1026.     if v.type == "program" then
  1027.         pc = _PROGRAM_OFFSET
  1028.         preProcLabels( v )
  1029.         for i=1, #v.prog do
  1030.             preProc( v.prog[ i ], env )
  1031.         end
  1032.         preProcMem( BC_HALT )
  1033.         eop = pc
  1034.         return
  1035.     elseif v.type == "line" then
  1036.         pcs[ v.line ] = pc
  1037.         if #v.value > 0 then
  1038.             for i=1, #v.value do
  1039.                 preProc( v.value[ i ], env )
  1040.             end
  1041.         else
  1042.             preProc( v.value, env )
  1043.         end
  1044.     elseif v.type == "num" or v.type == "str" then
  1045.         preProcMem( BC_PUSH, v.value )
  1046.     elseif v.type == "label" then
  1047.         pcs[ v.name ] = pc
  1048.         addToMem2( BC_VDEF, v.name )
  1049.         addToMem2( BC_PUSH, pc )
  1050.         addToMem2( BC_VSET, v.name )
  1051.     elseif v.type == "defun" then
  1052.         preProcMem( BC_JUMP, 1 )
  1053.         addToMem2( BC_VDEF, v.name )
  1054.         addToMem2( BC_PUSH, pc )
  1055.         addToMem2( BC_VSET, v.name )
  1056.         preProcMem( BC_EXPECT, 1 )
  1057.         for i=1, #v.vararg do
  1058.             preProcMem( BC_VDEF, 1 )
  1059.             preProcMem( BC_VSET, 1 )
  1060.         end
  1061.         preProc( v.value )
  1062.         for i=1, #v.vararg do
  1063.             preProcMem( BC_VFREE, 1 )
  1064.         end
  1065.         preProcMem( BC_RET )
  1066.         defuncs[ v.name ] = pc
  1067.     elseif v.type == "goto" then
  1068.         preProcMem( BC_JUMP, 1 )
  1069.     elseif v.type == "return" then
  1070.         preProcMem( BC_RET )
  1071.     elseif v.type == "gosub" then
  1072.         if v.value.type == "num" then
  1073.             preProcMem( BC_PUSH, 1 )
  1074.         else
  1075.             preProc( v.value )
  1076.         end
  1077.         preProcMem( BC_GOSUB )
  1078.     elseif v.type == "array" then
  1079.         preProcMem( BC_VDEF, v.name )
  1080.         preProcMem( BC_CARR )
  1081.         preProcMem( BC_VSET, v.name )
  1082.     elseif v.type == "var_def" then
  1083.         preProcMem( BC_VDEF, v.name )
  1084.     elseif v.type == "var_defset" then
  1085.         preProcMem( BC_VDEF, v.name )
  1086.         preProc( v.value, env )
  1087.         preProcMem( BC_VSET, v.name )
  1088.     elseif v.type == "var_set" then
  1089.         preProc( v.value, env )
  1090.         preProcMem( BC_VSET, v.name )
  1091.     elseif v.type == "var_get" then
  1092.         preProcMem( BC_VGET, v.name )
  1093.     elseif v.type == "call" then
  1094.         for i=1, #v.args do
  1095.             preProc( v.args[ i ] )
  1096.         end
  1097.         if defuncs[ v.name ] then
  1098.             preProcMem( BC_ARGS, #v.args )
  1099.             preProcMem( BC_VGET, v.name )
  1100.             preProcMem( BC_GOSUB )
  1101.         else
  1102.             preProcMem( BC_ARGS, #v.args )
  1103.             preProcMem( BC_CALL, v.name )
  1104.         end
  1105.     elseif v.type == "if" then
  1106.         preProc( v.cond, env )
  1107.         preProcMem( BC_JPC, 0, 0 )
  1108.         preProc( v[ "then" ], env )
  1109.         pcs[ "if_end_"..cifcount ] = pc
  1110.         cifcount = cifcount + 1
  1111.     elseif v.type == "loop" then
  1112.         preProcMem( BC_VDEF, v.var )
  1113.         preProc( v.value, env )
  1114.         preProcMem( BC_VSET, v.var )
  1115.         if v.step then
  1116.             preProc( v.step, env )
  1117.             preProcMem( BC_STORE, 0 )
  1118.         end
  1119.         pcs[ "for_start_"..forloopc ] = pc
  1120.         forloopc = forloopc + 1
  1121.         for i=1, #v.prog do
  1122.             preProc( v.prog[ i ], env )
  1123.         end
  1124.         preProcMem( BC_VGET, v.var )
  1125.         if v.step then
  1126.             preProcMem( BC_LOAD, 0 )
  1127.             preProcMem( BC_ADD )
  1128.             preProcMem( BC_DUP )
  1129.             preProcMem( BC_VSET, v.var )
  1130.         else
  1131.             preProcMem( BC_PUSH, 1 )
  1132.             preProcMem( BC_ADD )
  1133.             preProcMem( BC_DUP )
  1134.             preProcMem( BC_VSET, v.var )
  1135.         end
  1136.         preProc( v.stepto, env )
  1137.         preProcMem( BC_CMP, 2 )
  1138.         preProcMem( BC_JPC, 0, 0 )
  1139.         preProcMem( BC_VFREE, v.var )
  1140.     elseif v.type == "binary" then
  1141.         preProc( v.left, env )
  1142.         preProc( v.right, env )
  1143.         preProcBin( v.op )
  1144.     end
  1145. end
  1146.  
  1147. local function printTable( t )
  1148.     local file = fs.open( "OUT", "w" )
  1149.     file.write( textutils.serialize( t ) )
  1150.     file.close()
  1151. end
  1152.  
  1153. local optBytes = 0
  1154. local function optimizeBinary( l, r, op, v )
  1155.     if type( l ) == "number" and type( r ) == "number" then
  1156.         optBytes = optBytes + 4
  1157.         if op == "+" then
  1158.             v.type = "num"
  1159.             v.value = l + r
  1160.         elseif op == "-" then
  1161.             v.type = "num"
  1162.             v.value = l - r
  1163.         elseif op == "*" then
  1164.             v.type = "num"
  1165.             v.value = l * r
  1166.         elseif op == "/" then
  1167.             v.type = "num"
  1168.             v.value = l / r
  1169.         elseif op == "%" then
  1170.             v.type = "num"
  1171.             v.value = l % r
  1172.         elseif op == "^" then
  1173.             v.type = "num"
  1174.             v.value = l ^ r
  1175.         elseif op == "=" then
  1176.             v.type = "num"
  1177.             v.value = (l == r) and 1 or 0
  1178.         elseif op == "<>" then
  1179.             v.type = "num"
  1180.             v.value = l ~= r and 1 or 0
  1181.         elseif op == ">" then
  1182.             v.type = "num"
  1183.             v.value = l > r and 1 or 0
  1184.         elseif op == "<" then
  1185.             v.type = "num"
  1186.             v.value = l < r and 1 or 0
  1187.         elseif op == ">=" then
  1188.             v.type = "num"
  1189.             v.value = l >= r and 1 or 0
  1190.         elseif op == "<=" then
  1191.             v.type = "num"
  1192.             v.value = l <= r and 1 or 0
  1193.         elseif op == "and" then
  1194.             v.type = "num"
  1195.             v.value = ((l and r) == 1) and 1 or 0
  1196.         elseif op == "or" then
  1197.             v.type = "num"
  1198.             v.value = ((l or r) == 1) and 1 or 0
  1199.         else
  1200.             error( "BASIC: optimize error", 0 )
  1201.         end
  1202.         return true
  1203.     elseif type( l ) == "string" and type( r ) == "string" then
  1204.         optBytes = optBytes + #l + #r + 4
  1205.         if op == "+" then
  1206.             v.type = "str"
  1207.             v.value = l .. r
  1208.         else
  1209.             error( "BASIC: optimize error", 0 )
  1210.         end
  1211.         return true
  1212.     end
  1213.     return false
  1214. end
  1215.  
  1216. local backOne = false
  1217. local function optimize( v, t )
  1218.     if v.type == "program" then
  1219.         local i = 1
  1220.         while i <= #v.prog do
  1221.             optimize( v.prog[ i ] )
  1222.             i = i + 1
  1223.         end
  1224.         --printTable( v )
  1225.         if t == nil then
  1226.             print( "OPTIMIZED: "..optBytes.." BYTES" )
  1227.         end
  1228.     elseif v.type == "num" then
  1229.         return tonumber( v.value )
  1230.     elseif v.type == "str" then
  1231.         return v.value
  1232.     elseif v.type == "line" then
  1233.         if #v.value > 0 then
  1234.             for j = 1, #v.value do
  1235.                 while true do
  1236.                     optimize( v.value[ j ] )
  1237.                     if backOne ~= true then
  1238.                         backOne = false
  1239.                         break
  1240.                     end
  1241.                 end
  1242.             end
  1243.         else
  1244.             optimize( v.value )
  1245.         end
  1246.     elseif v.type == "defun" then
  1247.         while true do
  1248.             backOne = false
  1249.             optimize( v.value )
  1250.             if backOne ~= true then
  1251.                 backOne = false
  1252.                 break
  1253.             end
  1254.         end
  1255.     elseif v.type == "if" then
  1256.         while true do
  1257.             backOne = false
  1258.             optimize( v.cond )
  1259.             if backOne ~= true then
  1260.                 backOne = false
  1261.                 break
  1262.             end
  1263.         end
  1264.         optimize( v[ "then" ] )
  1265.     elseif v.type == "var_defset" then
  1266.         while true do
  1267.             backOne = false
  1268.             optimize( v.value )
  1269.             if backOne ~= true then
  1270.                 backOne = false
  1271.                 break
  1272.             end
  1273.         end
  1274.     elseif v.type == "var_set" then
  1275.         while true do
  1276.             backOne = false
  1277.             optimize( v.value )
  1278.             if backOne ~= true then
  1279.                 backOne = false
  1280.                 break
  1281.             end
  1282.         end
  1283.     elseif v.type == "loop" then
  1284.         while true do
  1285.             backOne = false
  1286.             optimize( v.value )
  1287.             if backOne ~= true then
  1288.                 backOne = false
  1289.                 break
  1290.             end
  1291.         end
  1292.         if v.step then
  1293.             while true do
  1294.                 backOne = false
  1295.                 optimize( v.step )
  1296.                 if backOne ~= true then
  1297.                     backOne = false
  1298.                     break
  1299.                 end
  1300.             end
  1301.         end
  1302.         for i=1, #v.prog do
  1303.             optimize( v.prog[ i ] )
  1304.         end
  1305.         while true do
  1306.             backOne = false
  1307.             optimize( v.stepto )
  1308.             if backOne ~= true then
  1309.                 backOne = false
  1310.                 break
  1311.             end
  1312.         end
  1313.     elseif v.type == "call" then
  1314.         for c=1, #v.args do
  1315.             while true do
  1316.                 backOne = false
  1317.                 optimize( v.args[ c ] )
  1318.                 if backOne ~= true then
  1319.                     backOne = false
  1320.                     break
  1321.                 end
  1322.             end
  1323.         end
  1324.     elseif v.type == "binary" then
  1325.         local c = optimizeBinary( optimize( v.left ), optimize( v.right ), v.op, v )
  1326.         if c == true then
  1327.             backOne = true
  1328.         end
  1329.     end
  1330. end
  1331.  
  1332. local function compileBinary( o )
  1333.     if o == "+" then
  1334.         addToMem( BC_ADD )
  1335.     elseif o == "-" then
  1336.         addToMem( BC_SUB )
  1337.     elseif o == "*" then
  1338.         addToMem( BC_MUL )
  1339.     elseif o == "/" then
  1340.         addToMem( BC_DIV )
  1341.     elseif o == "^" then
  1342.         addToMem( BC_POW )
  1343.     elseif o == "%" then
  1344.         addToMem( BC_MOD )
  1345.     elseif o == "=" then
  1346.         addToMem( BC_CMP, 0 )
  1347.     elseif o == "<" then
  1348.         addToMem( BC_CMP, 3 )
  1349.     elseif o == ">" then
  1350.         addToMem( BC_CMP, 2 )
  1351.     elseif o == ">=" then
  1352.         addToMem( BC_CMP, 4 )
  1353.     elseif o == "<=" then
  1354.         addToMem( BC_CMP, 5 )
  1355.     elseif o == "<>" then
  1356.         addToMem( BC_CMP, 1 )
  1357.     elseif o == "and" then
  1358.         addToMem( BC_AND )
  1359.     elseif o == "or" then
  1360.         addToMem( BC_OR )
  1361.     end
  1362. end
  1363. local ifcount = 0
  1364. local varoffset = 1
  1365. local forloop = 0
  1366. local function comp( v, tt )
  1367.     if v.type == "program" then
  1368.         local prg = {}
  1369.         currMem = prg
  1370.         optBytes = 0
  1371.         optimize( v, tt )
  1372.         preProc( v, Enviroment() )
  1373.         pc = _PROGRAM_OFFSET
  1374.         for i=1, #v.prog do
  1375.             comp( v.prog[ i ] )
  1376.         end
  1377.         addToMem( BC_HALT )
  1378.         currMem = nil
  1379.         return prg
  1380.     elseif v.type == "line" then
  1381.         if #v.value > 0 then
  1382.             for i=1, #v.value do
  1383.                 comp( v.value[ i ] )
  1384.             end
  1385.         else
  1386.             comp( v.value )
  1387.         end
  1388.     elseif v.type == "num" then
  1389.         addToMem( BC_PUSH, tonumber( v.value ) )
  1390.     elseif v.type == "str" then
  1391.         addToMem( BC_PUSH, v.value )
  1392.     elseif v.type == "goto" then
  1393.         addToMem( BC_JUMP, pcs[ v.value ] )
  1394.     elseif v.type == "gosub" then
  1395.         comp( v.value )
  1396.         addToMem( BC_GOSUB )
  1397.     elseif v.type == "return" then
  1398.         addToMem( BC_RET )
  1399.     elseif v.type == "array" then
  1400.         addToMem( BC_VDEF, v.name )
  1401.         addToMem( BC_CARR )
  1402.         addToMem( BC_VSET, v.name )
  1403.     elseif v.type == "defun" then
  1404.         addToMem( BC_JUMP, defuncs[ v.name ] )
  1405.         addToMem( BC_EXPECT, #v.vararg )
  1406.         for i=1, #v.vararg do
  1407.             addToMem( BC_VDEF, v.vararg[ i ] )
  1408.             addToMem( BC_VSET, v.vararg[ i ] )
  1409.         end
  1410.         comp( v.value )
  1411.         for i=1, #v.vararg do
  1412.             addToMem( BC_VFREE, v.vararg[ i ] )
  1413.         end
  1414.         addToMem( BC_RET )
  1415.     elseif v.type == "var_def" then
  1416.         addToMem( BC_VDEF, v.name )
  1417.     elseif v.type == "var_defset" then
  1418.         addToMem( BC_VDEF, v.name )
  1419.         comp( v.value )
  1420.         addToMem( BC_VSET, v.name )
  1421.     elseif v.type == "var_set" then
  1422.         comp( v.value )
  1423.         addToMem( BC_VSET, v.name )
  1424.     elseif v.type == "var_get" then
  1425.         addToMem( BC_VGET, v.name )
  1426.     elseif v.type == "call" then
  1427.         for i=1, #v.args do
  1428.             comp( v.args[ i ] )
  1429.         end
  1430.         if defuncs[ v.name ] then
  1431.             addToMem( BC_ARGS, #v.args )
  1432.             addToMem( BC_VGET, v.name )
  1433.             addToMem( BC_GOSUB )
  1434.         else
  1435.             addToMem( BC_ARGS, #v.args )
  1436.             addToMem( BC_CALL, v.name )
  1437.         end
  1438.     elseif v.type == "if" then
  1439.         comp( v.cond )
  1440.         addToMem( BC_JPC, 0, pcs[ "if_end_"..ifcount ] )
  1441.         ifcount = ifcount + 1
  1442.         comp( v[ "then" ] )
  1443.     elseif v.type == "loop" then
  1444.         addToMem( BC_VDEF, v.var )
  1445.         comp( v.value )
  1446.         addToMem( BC_VSET, v.var )
  1447.         local vof = varoffset
  1448.         varoffset = varoffset + 1
  1449.         local vfl = forloop
  1450.         forloop = forloop + 1
  1451.         if v.step then
  1452.             comp( v.step )
  1453.             addToMem( BC_STORE, eop+vof )
  1454.         end
  1455.         for i=1, #v.prog do
  1456.             comp( v.prog[i] )
  1457.         end
  1458.         addToMem( BC_VGET, v.var )
  1459.         if v.step then
  1460.             addToMem( BC_LOAD, eop+vof )
  1461.             addToMem( BC_ADD )
  1462.             addToMem( BC_DUP )
  1463.             addToMem( BC_VSET, v.var )
  1464.         else
  1465.             addToMem( BC_PUSH, 1 )
  1466.             addToMem( BC_ADD )
  1467.             addToMem( BC_DUP )
  1468.             addToMem( BC_VSET, v.var )
  1469.         end
  1470.         comp( v.stepto )
  1471.         addToMem( BC_CMP, 2 )
  1472.         addToMem( BC_JPC, 0, pcs[ "for_start_"..vfl ] )
  1473.         addToMem( BC_VFREE, v.var )
  1474.     elseif v.type == "binary" then
  1475.         comp( v.left )
  1476.         comp( v.right )
  1477.         compileBinary( v.op )
  1478.     end
  1479. end
  1480. local function compile( v, t )
  1481.     return comp( parse( tokenize( inputFile( v ) ) ), t )
  1482. end
  1483. local floor = math.floor
  1484.  
  1485. --------INTERPRETER--------
  1486. local queue = os.queueEvent
  1487. local twrite = term.write
  1488. local setBgCol = term.setBackgroundColor
  1489. local setTxtCol = term.setTextColor
  1490. local tSetPos = term.setCursorPos
  1491. local highres = false
  1492. local updated = false
  1493. local function pxl( x, y, chr )
  1494.     if x <= _w and y <= _h and x > 0 and y > 0 then
  1495.         if highres == true then
  1496.             canvas:setPixel( floor( x ), floor( y ), true )
  1497.             updated = true
  1498.         else
  1499.             tSetPos( x, y )
  1500.             twrite( chr )
  1501.         end
  1502.     end
  1503. end
  1504. local function setColor( b, f )
  1505.     setBgCol( COLO[ b ] )
  1506.     setTxtCol( COLO[ f ] )
  1507. end
  1508. local function loadToMemory( m, off, r )
  1509.     local off = off or 0
  1510.     if r then
  1511.         memory = {}
  1512.     end
  1513.     for i=1, #m do
  1514.         memory[ off+i ] = m[ i ]
  1515.     end
  1516.     return #m
  1517. end
  1518. local _LOADED_FILES = {}
  1519. local _CURR_FILES_OPENED = {}
  1520. local _CURR_FILE_OPENED = 0
  1521. local _CURR_NET_RECEIVE = {}
  1522. local _CURR_NET_SEND = {}
  1523. local _CURR_NET_USERS = {}
  1524. local _CAN_NET_SEND = true
  1525. local function simpleParse( str )
  1526.     str = str .. " "
  1527.     local t = {}
  1528.     local word = ""
  1529.     for i=1, #str do
  1530.         local chr = str:sub( i, i )
  1531.         if chr == " " or chr == "\t" or chr == "\n" then
  1532.             if #word > 0 then
  1533.                 t[ #t + 1 ] = word
  1534.                 word = ""
  1535.             end
  1536.         else
  1537.             word = word .. chr
  1538.         end
  1539.     end
  1540.     return t
  1541. end
  1542. local function generateIP( side )
  1543.     rednet.open( side )
  1544.     local count = 0
  1545.     local ip = math.random( 0xFF )..":"..math.random( 0xFF )..":"..math.random( 0xFF )
  1546.     while true do
  1547.         count = count + 1
  1548.         if count > 5 then
  1549.             break
  1550.         end
  1551.         rednet.broadcast( "check_ip "..ip, "basip" )
  1552.         local _, msg = rednet.receive( "basip", .5 )
  1553.         if msg == "" then
  1554.             break
  1555.         end
  1556.         msg = simpleParse( msg or "" )
  1557.         if msg[ 1 ] == "change_ip" then
  1558.             ip = math.random( 0xFF )..":"..math.random( 0xFF )..":"..math.random( 0xFF )
  1559.         else
  1560.             break
  1561.         end
  1562.     end
  1563.     rednet.close( side )
  1564.     return ip
  1565. end
  1566. local _timers = {}
  1567. function Enviroment()
  1568.     return {
  1569.         [ "vars" ] = {
  1570.             [ "keystr" ] = "";
  1571.             [ "cycles" ] = 0;
  1572.             [ "createtimer" ] = function( time )
  1573.                 _timers[ #_timers + 1 ] = time or 0
  1574.                 return #_timers
  1575.             end;
  1576.             [ "settimer" ] = function( id, time )
  1577.                 if _timers[ id ] then
  1578.                     _timers[ id ] = time or 0
  1579.                 end
  1580.             end;
  1581.             [ "gettimer" ] = function( id )
  1582.                 if _timers[ id ] ~= nil then
  1583.                     return _timers[ id ]
  1584.                 end
  1585.             end;
  1586.             [ "print" ] = print;
  1587.             [ "write" ] = write;
  1588.             [ "input" ] = function( a, b )
  1589.                 write( a.." " )
  1590.                 return _read( b )
  1591.             end;
  1592.             [ "clear" ] = term.clear;
  1593.             [ "color" ] = setColor;
  1594.             [ "cursor" ] = tSetPos;
  1595.             [ "chr" ] = string.char;
  1596.             [ "int" ] = function( x )
  1597.                 return floor( tonumber( x ) )
  1598.             end;
  1599.             [ "str" ] = tostring;
  1600.             [ "num" ] = tonumber;
  1601.             [ "len" ] = function( x )
  1602.                 return #x
  1603.             end;
  1604.             [ "mid" ] = function( str, a, b )
  1605.                 b = b or #str - a
  1606.                 return str:sub( a, a+b )
  1607.             end;
  1608.             [ "left" ] = function( str, a )
  1609.                 return str:sub( 1, a )
  1610.             end;
  1611.             [ "right" ] = function( str, a )
  1612.                 a = a - 1
  1613.                 return str:sub( #str-a, #str )
  1614.             end;
  1615.             [ "btn" ] = function( x )
  1616.                 if buttons[ x ] then
  1617.                     return buttons[ x ]
  1618.                 end
  1619.                 return 0
  1620.             end;
  1621.             [ "hex" ] = function( x )
  1622.                 return tonumber( x, 16 )
  1623.             end;
  1624.             [ "abs" ] = math.abs;
  1625.             [ "atn" ] = math.atan;
  1626.             [ "cos" ] = math.cos;
  1627.             [ "sin" ] = math.sin;
  1628.             [ "exp" ] = math.exp;
  1629.             [ "log" ] = math.log;
  1630.             [ "rnd" ] = math.random;
  1631.             [ "sqr" ] = math.sqrt;
  1632.             [ "tan" ] = math.tan;
  1633.             [ "rad" ] = math.rad;
  1634.             [ "deg" ] = math.deg;
  1635.             [ "sgn" ] = function( x )
  1636.                 if x < 0 then
  1637.                     return -1
  1638.                 elseif x > 0 then
  1639.                     return 1
  1640.                 else
  1641.                     return 0
  1642.                 end
  1643.             end;
  1644.             [ "fload" ] = function( fn, isbyte )
  1645.                 if fs.exists( fn ) == false then
  1646.                     return PC
  1647.                 end
  1648.                 if _LOADED_FILES[ fn ] then
  1649.                     if _LOADED_FILES[ fn ][ 2 ] == cont then
  1650.                         return _LOADED_FILES[ fn ][ 1 ]
  1651.                     end
  1652.                 end
  1653.                 local mem
  1654.                 if fn:sub( #fn-2, #fn ) == "bas" then
  1655.                     local file = fs.open( fn, 'r' )
  1656.                     local cont = file.readAll()
  1657.                     currFile = fn
  1658.                     mem = compile( cont, true )
  1659.                     file.close()
  1660.                 elseif fn:sub( #fn, #fn ) == "o" then
  1661.                     mem = makeBytecode( readBytecodeFile( fn ) )
  1662.                 end
  1663.                 local s = _PROGRAM_OFFSET
  1664.                 _LOADED_FILES[ fn ] = {
  1665.                     s, cont
  1666.                 }
  1667.                 _PROGRAM_OFFSET = _PROGRAM_OFFSET + loadToMemory( mem, _PROGRAM_OFFSET - 1 )
  1668.                 return s
  1669.             end;
  1670.             [ "fexists" ] = function( fn )
  1671.                 if fs.exists( fn ) then
  1672.                     return 1
  1673.                 end
  1674.                 return 0
  1675.             end;
  1676.             [ "flist" ] = fs.list;
  1677.             [ "fdel"] = fs.delete;
  1678.             [ "frdonly" ] = function( x )
  1679.                 if fs.isReadOnly( x ) then
  1680.                     return 1
  1681.                 else
  1682.                     return 0
  1683.                 end
  1684.             end;
  1685.             [ "fisdir" ] = function( x )
  1686.                 if fs.isDir( x ) then
  1687.                     return 1
  1688.                 else
  1689.                     return 0
  1690.                 end
  1691.             end;
  1692.             [ "fconext" ] = function()
  1693.                 local n = #_CURR_FILES_OPENED
  1694.                 if n == 0 then return end
  1695.                 _CURR_FILE_OPENED = _CURR_FILE_OPENED + 1
  1696.                 if _CURR_FILE_OPENED > n then
  1697.                     _CURR_FILE_OPENED = 1
  1698.                 end
  1699.             end;
  1700.             [ "fcoprev" ] = function()
  1701.                 local n = #_CURR_FILES_OPENED
  1702.                 if n == 0 then return end
  1703.                 _CURR_FILE_OPENED = _CURR_FILE_OPENED - 1
  1704.                 if _CURR_FILE_OPENED <= 0 then
  1705.                     _CURR_FILE_OPENED = n
  1706.                 end
  1707.             end;
  1708.             [ "fopen" ] = function( fn, t )
  1709.                 if fs.exists( fn ) == false then return 0 end
  1710.                 _CURR_FILE_OPENED = _CURR_FILE_OPENED + 1
  1711.                 _CURR_FILES_OPENED[ _CURR_FILE_OPENED ] = fs.open( fn, t )
  1712.                 return 1
  1713.             end;
  1714.             [ "fread" ] = function()
  1715.                 if fileHeader ~= nil then
  1716.                     return _CURR_FILES_OPENED[ _CURR_FILE_OPENED ].readAll()
  1717.                 else
  1718.                     return 0
  1719.                 end
  1720.             end;
  1721.             [ "freadln" ] = function()
  1722.                 if _CURR_FILES_OPENED[ _CURR_FILE_OPENED ] ~= nil then
  1723.                     local ln = _CURR_FILES_OPENED[ _CURR_FILE_OPENED ].readLine()
  1724.                     if ln == nil then
  1725.                         return 0
  1726.                     else
  1727.                         return ln
  1728.                     end
  1729.                 else
  1730.                     return 0
  1731.                 end
  1732.             end;
  1733.             [ "fwrite" ] = function( x )
  1734.                 if _CURR_FILES_OPENED[ _CURR_FILE_OPENED ] ~= nil then
  1735.                     _CURR_FILES_OPENED[ _CURR_FILE_OPENED ].write( x )
  1736.                 else
  1737.                     return 0
  1738.                 end
  1739.             end;
  1740.             [ "fwriteln" ] = function( x )
  1741.                 if _CURR_FILES_OPENED[ _CURR_FILE_OPENED ] ~= nil then
  1742.                     _CURR_FILES_OPENED[ _CURR_FILE_OPENED ].writeLine( x )
  1743.                 else
  1744.                     return 0
  1745.                 end
  1746.             end;
  1747.             [ "fclose" ] = function()
  1748.                 if _CURR_FILES_OPENED[ _CURR_FILE_OPENED ] ~= nil then
  1749.                     _CURR_FILES_OPENED[ _CURR_FILE_OPENED ].close()
  1750.                     _CURR_FILES_OPENED[ _CURR_FILE_OPENED ] = nil
  1751.                     _CURR_FILE_OPENED = _CURR_FILE_OPENED - 1
  1752.                 else
  1753.                     return 0
  1754.                 end
  1755.             end;
  1756.             [ "hires" ] = function()
  1757.                 if fs.exists( "hiresAPI" ) == false then
  1758.                     shell.run( "pastebin", "get", "TFFJwxvp", "hiresAPI" )
  1759.                     os.loadAPI( "hiresAPI" )
  1760.                 end
  1761.                 canvas = hiresAPI.Canvas.create()
  1762.                 highres = true
  1763.                 _w = _w * 2
  1764.                 _h = _h * 3
  1765.             end;
  1766.             [ "lores" ] = function()
  1767.                 highres = false
  1768.                 _w, _h = term.getSize()
  1769.             end;
  1770.             [ "pixel" ] = pxl;
  1771.             [ "sprite" ] = function( arr, x, y, w, h )
  1772.                 x = x - 1
  1773.                 y = y - 1
  1774.                 local wh = (w*h)-1
  1775.                 for i = 0, wh do
  1776.                     if highres == false then
  1777.                         if arr[ i+1 ] then
  1778.                             setBgCol( COLO[ arr[ i+1 ] ] )
  1779.                         end
  1780.                         pxl( x + (i%w), y + (i/w), " " )
  1781.                     else
  1782.                         if arr[ i+1 ] == 0 then
  1783.                             pxl( x + (i%w), y + (i/w) )
  1784.                         end
  1785.                     end
  1786.                 end
  1787.             end;
  1788.             [ "store" ] = function( arr, x, y )
  1789.                 if type( arr ) == "table" then
  1790.                     arr[ x ] = y
  1791.                 else
  1792.                     printError( "BASIC: expected array to store to" )
  1793.                     isRunning = false
  1794.                 end
  1795.             end;
  1796.             [ "storen" ] = function( arr, x )
  1797.                 if type( arr ) == "table" then
  1798.                     arr[ #arr+1 ] = x
  1799.                 else
  1800.                     printError( "BASIC: expected array to store to" )
  1801.                     isRunning = false
  1802.                 end
  1803.             end;
  1804.             [ "read" ] = function( arr, x )
  1805.                 if type( arr ) == "table" then
  1806.                     return arr[ x ] or "none"
  1807.                 else
  1808.                     printError( "BASIC: expected array to read from" )
  1809.                     isRunning = false
  1810.                 end
  1811.             end;
  1812.             [ "shutdown" ] = function()
  1813.                 print( "Shutdown in 5 seconds..." )
  1814.                 sleep( 5 )
  1815.                 os.shutdown()
  1816.             end;
  1817.             [ "reboot" ] = function()
  1818.                 print( "Rebooting in 5 seconds..." )
  1819.                 sleep( 5 )
  1820.                 os.reboot()
  1821.             end;
  1822.             [ "label" ] = function( x )
  1823.                 os.setComputerLabel( x )
  1824.             end;
  1825.             [ "exit" ] = function()
  1826.                 isRunning = false
  1827.             end;
  1828.             [ "dispose" ] = function()
  1829.                 while SP > 0 do
  1830.                     spop()
  1831.                 end
  1832.             end;
  1833.             [ "netcreate" ] = function( auto )
  1834.                 local net = {}
  1835.                 if auto then
  1836.                     if peripheral.isPresent( auto ) then
  1837.                         if peripheral.getType( auto ) == "modem" then
  1838.                             net[ "side" ] = auto
  1839.                             net[ "ip" ] = generateIP( auto )
  1840.                             net[ "opened" ] = false
  1841.                         else
  1842.                             return
  1843.                         end
  1844.                     else
  1845.                         return
  1846.                     end
  1847.                 else
  1848.                     local side = ""
  1849.                     local prhl = peripheral.getNames()
  1850.                     for i=1, #prhl do
  1851.                         if peripheral.getType( prhl[ i ] ) == "modem" then
  1852.                             side = prhl[ i ]
  1853.                         end
  1854.                     end
  1855.                     net[ "side" ] = side
  1856.                     net[ "ip" ] = generateIP( side )
  1857.                     net[ "opened" ] = false
  1858.                 end
  1859.                 return net
  1860.             end;
  1861.             [ "netopen" ] = function( net )
  1862.                 if type( net ) == "table" then
  1863.                     rednet.open( net[ "side" ] )
  1864.                     net[ "opened" ] = true
  1865.                     _CURR_NET_SEND = {
  1866.                         [ "ip" ] = net.ip;
  1867.                         [ "type" ] = "";
  1868.                         [ "msg" ] = "";
  1869.                     }
  1870.                     _CURR_NET_USERS = {}
  1871.                 end
  1872.             end;
  1873.             [ "netclose" ] = function( net )
  1874.                 if type( net ) == "table" then
  1875.                     rednet.close( net[ "side" ] )
  1876.                     net[ "opened" ] = false
  1877.                 end
  1878.             end;
  1879.             [ "netmyip" ] = function( net )
  1880.                 if type( net ) == "table" then
  1881.                     return net.ip
  1882.                 end
  1883.             end;
  1884.             [ "netreceive" ] = function( net )
  1885.                 if net[ "opened" ] == true then
  1886.                     if _CURR_NET_USERS.senderIP then
  1887.                         if _CURR_NET_USERS[ _CURR_NET_USERS.senderIP ] == nil then
  1888.                             _CURR_NET_USERS[ _CURR_NET_USERS.senderIP ] = _CURR_NET_USERS.senderID
  1889.                         end
  1890.                     end
  1891.                 end
  1892.             end;
  1893.             [ "netgetid" ] = function( net )
  1894.                 if net[ "opened" ] == true then
  1895.                     if _CURR_NET_RECEIVE.senderID then
  1896.                         return _CURR_NET_RECEIVE.senderID
  1897.                     end
  1898.                 end
  1899.                 return 0
  1900.             end;
  1901.             [ "netgetip" ] = function( net )
  1902.                 if net[ "opened" ] == true then
  1903.                     if _CURR_NET_RECEIVE.senderIP then
  1904.                         return _CURR_NET_RECEIVE.senderIP
  1905.                     end
  1906.                 end
  1907.                 return 0
  1908.             end;
  1909.             [ "netgettype" ] = function( net )
  1910.                 if net[ "opened" ] == true then
  1911.                     if _CURR_NET_RECEIVE.senderMsgType then
  1912.                         return _CURR_NET_RECEIVE.senderMsgType
  1913.                     end
  1914.                 end
  1915.                 return 0
  1916.             end;
  1917.             [ "netgetmessage" ] = function( net )
  1918.                 if net[ "opened" ] == true then
  1919.                     if _CURR_NET_RECEIVE.senderMsg then
  1920.                         return _CURR_NET_RECEIVE.senderMsg
  1921.                     end
  1922.                 end
  1923.                 return 0
  1924.             end;
  1925.             [ "netclearbuffer" ] = function()
  1926.                 local ip = _CURR_NET_SEND.ip
  1927.                 _CURR_NET_SEND = {
  1928.                     [ "ip" ] = ip;
  1929.                     [ "type" ] = "";
  1930.                     [ "msg" ] = "";
  1931.                 }
  1932.             end;
  1933.             [ "nettype" ] = function( t )
  1934.                 _CURR_NET_SEND[ "type" ] = t
  1935.             end;
  1936.             [ "netmessage" ] = function( t )
  1937.                 _CURR_NET_SEND[ "msg" ] = t
  1938.             end;
  1939.             [ "netsend" ] = function( ip )
  1940.                 if _CAN_NET_SEND == true then
  1941.                     if _CURR_NET_USERS[ ip ] == nil then
  1942.                         rednet.broadcast( "ip "..ip, "basip" )
  1943.                         local id, msg = rednet.receive( "basip" )
  1944.                         local msg = simpleParse( msg or "" )
  1945.                         if msg[ 1 ] == ip then
  1946.                             _CURR_NET_USERS[ ip ] = id
  1947.                         end
  1948.                     end
  1949.                     rednet.send( _CURR_NET_USERS[ ip ], _CURR_NET_SEND[ "ip" ].." ".._CURR_NET_SEND[ "type" ].." ".._CURR_NET_SEND[ "msg" ], "bas" )
  1950.                     _CAN_NET_SEND = false
  1951.                 end
  1952.             end;
  1953.         };
  1954.         [ "set" ] = function( self, x, y )
  1955.             local v = self.vars
  1956.             if v[ x ] then
  1957.                 v[ x ] = y
  1958.             else
  1959.                 printError( "BASIC: variable <"..x.."> is not defined!" )
  1960.                 isRunning = false
  1961.             end
  1962.         end;
  1963.         [ "get" ] = function( self, x )
  1964.             local v = self.vars
  1965.             if v[ x ] then
  1966.                 return v[ x ]
  1967.             else
  1968.                 if x then
  1969.                     printError( "BASIC: variable <"..x.."> is not defined!" )
  1970.                 end
  1971.                 isRunning = false
  1972.                 return nil
  1973.             end
  1974.         end;
  1975.         [ "def" ] = function( self, x )
  1976.             self.vars[ x ] = 0
  1977.         end;
  1978.         [ "isDefined" ] = function( self, x )
  1979.             return self.vars[ x ] ~= nil
  1980.         end;
  1981.         [ "free" ] = function( self, x )
  1982.             local v = self.vars
  1983.             if v[ x ] then
  1984.                 v[ x ] = nil
  1985.             else
  1986.                 printError( "BASIC: variable <"..x.."> is not defined!" )
  1987.                 isRunning = false
  1988.             end
  1989.         end;
  1990.     }
  1991. end
  1992.  
  1993. local function fetch()
  1994.     local v = memory[ PC ]
  1995.     PC = PC + 1
  1996.     return v
  1997. end
  1998. local function cycle( opcode, env )
  1999.     if opcode == BC_HALT then
  2000.         isRunning = false
  2001.     elseif opcode == BC_PUSH then
  2002.         spush( fetch() )
  2003.     elseif opcode == BC_POP then
  2004.         spop()
  2005.     elseif opcode == BC_VDEF then
  2006.         env:def( fetch() )
  2007.     elseif opcode == BC_VSET then
  2008.         env:set( fetch(), spop() )
  2009.     elseif opcode == BC_VGET then
  2010.         spush( env:get( fetch() ) )
  2011.     elseif opcode == BC_VFREE then
  2012.         env:free( fetch() )
  2013.     elseif opcode == BC_ARGS then
  2014.         local argc = fetch()
  2015.         local args = {}
  2016.         if (SP - argc) < 0 then
  2017.             printError( "BASIC: stack underflow" )
  2018.             printError( "PC: "..PC )
  2019.             isRunning = false
  2020.             return
  2021.         end
  2022.         for i=1, argc do
  2023.             args[ argc-(i-1) ] = spop()
  2024.         end
  2025.         spush( args )
  2026.     elseif opcode == BC_CALL then
  2027.         local ret = env:get( fetch() )( unpack( spop() ) )
  2028.         if ret then
  2029.             spush( ret )
  2030.         end
  2031.     elseif opcode == BC_ADD then
  2032.         local y = spop()
  2033.         local x = spop()
  2034.         if type( x ) == "string" or type( y ) == "string" then
  2035.             spush( x .. y )
  2036.         else
  2037.             spush( x + y )
  2038.         end
  2039.     elseif opcode == BC_SUB then
  2040.         local y = spop()
  2041.         spush( spop() - y )
  2042.     elseif opcode == BC_MUL then
  2043.         local y = spop()
  2044.         spush( spop() * y )
  2045.     elseif opcode == BC_DIV then
  2046.         local y = spop()
  2047.         spush( spop() / y )
  2048.     elseif opcode == BC_MOD then
  2049.         local y = spop()
  2050.         spush( spop() % y )
  2051.     elseif opcode == BC_POW then
  2052.         local y = spop()
  2053.         spush( spop() ^ y )
  2054.     elseif opcode == BC_JUMP then
  2055.         PC = fetch()
  2056.     elseif opcode == BC_GOSUB then
  2057.         local to = spop()
  2058.         rpush( PC )
  2059.         PC = to
  2060.     elseif opcode == BC_RET then
  2061.         PC = rpop()
  2062.     elseif opcode == BC_CMP then
  2063.         local t = fetch()
  2064.         local y = spop()
  2065.         if t == 0 then
  2066.             spush( spop() == y and 1 or 0 )
  2067.         elseif t == 1 then
  2068.             spush( spop() ~= y and 1 or 0 )
  2069.         elseif t == 2 then
  2070.             spush( spop() > y and 1 or 0 )
  2071.         elseif t == 3 then
  2072.             spush( spop() < y and 1 or 0 )
  2073.         elseif t == 4 then
  2074.             spush( spop() >= y and 1 or 0 )
  2075.         elseif t == 5 then
  2076.             spush( spop() <= y and 1 or 0 )
  2077.         end
  2078.     elseif opcode == BC_JPC then
  2079.         local cond
  2080.         local t = fetch()
  2081.         if spop() == t then
  2082.             PC = fetch()
  2083.         else
  2084.             PC = PC + 1
  2085.         end
  2086.     elseif opcode == BC_STORE then
  2087.         memory[ fetch() ] = spop()
  2088.     elseif opcode == BC_LOAD then
  2089.         spush( memory[ fetch() ] )
  2090.     elseif opcode == BC_DUP then
  2091.         local pop = spop()
  2092.         spush( pop )
  2093.         spush( pop )
  2094.     elseif opcode == BC_AND then
  2095.         local y = spop()
  2096.         spush( ((spop() and y) == 1) and 1 or 0 )
  2097.     elseif opcode == BC_OR then
  2098.         local y = spop()
  2099.         spush( ((spop() or y) == 1) and 1 or 0 )
  2100.     elseif opcode == BC_CARR then
  2101.         spush( {} )
  2102.     elseif opcode == BC_EXPECT then
  2103.         local v = spop()
  2104.         local n = fetch()
  2105.         if type( v ) ~= "table" then
  2106.             printError( "BASIC: interpreter error" )
  2107.             printError( "PC: "..PC )
  2108.             printError( "Expected: args" )
  2109.             isRunning = false
  2110.         end
  2111.         if n == #v then
  2112.             for i=#v, 1, -1 do
  2113.                 spush( v[ i ] )
  2114.             end
  2115.         else
  2116.             printError( "BASIC: interpreter error" )
  2117.             printError( "PC: "..PC )
  2118.             printError( "Expected: "..n.." args" )
  2119.             isRunning = false
  2120.         end
  2121.     else
  2122.         printError( "BASIC: interpreter error" )
  2123.         printError( "PC: "..PC )
  2124.         printError( "STACK {" )
  2125.         for i=1, #stack do
  2126.             if i == #stack then
  2127.                 write( stack[ i ] )
  2128.             else
  2129.                 write( stack[ i ]..", " )
  2130.             end
  2131.         end
  2132.         print()
  2133.         printError( "}" )
  2134.         isRunning = false
  2135.     end
  2136. end
  2137.  
  2138. local bc_END_STRING = 0x0
  2139. local bc_START_STRING = 0x1
  2140. local bc_NEXT_BC = 0x2
  2141. local bc_NEXT_ARG = 0x3
  2142. local function makeByteTable( bc )
  2143.     local b = {}
  2144.     local check = false
  2145.     local i = 1
  2146.     while i <= #bc do
  2147.         local _byte = bc[ i ]
  2148.         if check == false then
  2149.             local m = opToName[ _byte ]
  2150.             if m[ 1 ] == "HALT" then
  2151.                 check = true
  2152.             end
  2153.             b[ #b + 1 ] = bc_NEXT_BC
  2154.             b[ #b + 1 ] = _byte
  2155.             local _ = 0
  2156.             for j=1, m[ 2 ] do
  2157.                 local v = bc[ i+j ]
  2158.                 if type( v ) == "string" then
  2159.                     b[ #b + 1 ] = bc_START_STRING
  2160.                     for c=1, #v do
  2161.                         b[ #b + 1 ] = string.byte( v:sub( c, c ) )
  2162.                     end
  2163.                     b[ #b + 1 ] = bc_END_STRING
  2164.                 elseif type( v ) == "number" then
  2165.                     b[ #b + 1 ] = bc_NEXT_ARG
  2166.                     b[ #b + 1 ] = v
  2167.                 end
  2168.                 _ = _ + 1
  2169.             end
  2170.             i = (i + 1) + _
  2171.         else
  2172.             b[ #b + 1 ] = bc[ i ]
  2173.             i = i + 1
  2174.         end
  2175.     end
  2176.     return b
  2177. end
  2178. local function makeRunnableNET( fn, bc )
  2179.     local f=fn.."_tmp"
  2180.     local bcc = ""
  2181.     for i=1, #bc do
  2182.         local str = string.format( "%x", bc[ i ] )
  2183.         if #str == 1 then
  2184.             str = "0" .. str
  2185.         end
  2186.         bcc = bcc..str.." "
  2187.     end
  2188.     local file = fs.open( fn, 'w' )
  2189.     file.writeLine("local file=fs.open('"..f.."','w')")
  2190.     file.writeLine("file.write('"..bcc.."')")
  2191.     file.writeLine("file.close()")
  2192.     file.writeLine("shell.run('pastebin','run','nsMdcH6L','r','"..f.."')")
  2193.     file.writeLine("fs.delete('"..f.."')")
  2194.     file.close()
  2195. end
  2196. local function writeBytecodeToFile( fn, bc )
  2197.     local file = fs.open( fn, 'w' )
  2198.     local count = 1
  2199.     for i=1, #bc do
  2200.         if count >= 16 then
  2201.             count = 2
  2202.             file.write( "\n" )
  2203.             local str = string.format( "%x", bc[ i ] )
  2204.             if #str == 1 then
  2205.                 str = "0" .. str
  2206.             end
  2207.             file.write( str .. " " )
  2208.         else
  2209.             local str = string.format( "%x", bc[ i ] )
  2210.             if #str == 1 then
  2211.                 str = "0" .. str
  2212.             end
  2213.             count = count + 1
  2214.             file.write( str .. " " )
  2215.         end
  2216.     end
  2217.     file.close()
  2218. end
  2219. function readBytecodeFile( fn )
  2220.     local file = fs.open( fn, 'r' )
  2221.     local content = file.readAll()
  2222.     local t = {}
  2223.     file.close()
  2224.     for seg in content:gmatch "%S+" do
  2225.         t[#t + 1] = tonumber( seg, 16 )
  2226.     end
  2227.     return t
  2228. end
  2229. function makeBytecode( bc )
  2230.     local b = {}
  2231.     local check = false
  2232.     local i = 1
  2233.     local function fetch()
  2234.         local v = bc[ i ]
  2235.         i = i + 1
  2236.         return v
  2237.     end
  2238.     local function fetchString()
  2239.         local str = ""
  2240.         while true do
  2241.             local v = fetch()
  2242.             if v == bc_END_STRING then
  2243.                 break
  2244.             else
  2245.                 str = str .. string.char( v )
  2246.             end
  2247.         end
  2248.         return str
  2249.     end
  2250.     while i <= #bc do
  2251.         local tp = fetch()
  2252.         if tp == bc_NEXT_BC then
  2253.             local byte = fetch()
  2254.             local op = opToName[ byte ]
  2255.             local iter = op[ 2 ]
  2256.             b[ #b + 1 ] = byte
  2257.             for j=1, iter do
  2258.                 local nx = fetch()
  2259.                 if nx == bc_NEXT_ARG then
  2260.                     local x = fetch()
  2261.                     b[ #b + 1 ] = x
  2262.                 elseif nx == bc_START_STRING then
  2263.                     local x = fetchString()
  2264.                     b[ #b + 1 ] = x
  2265.                 else
  2266.                     error( "Expected Start of String or Start of Argument!", 0 )
  2267.                 end
  2268.             end
  2269.         else
  2270.             print( bc[ i-1 ] )
  2271.             error( "Expected bytecode!", 0 )
  2272.         end
  2273.     end
  2274.     return b
  2275. end
  2276.  
  2277. function interpret( env )
  2278.     PC = 1
  2279.     SP = 0
  2280.     jSP = 0
  2281.     stack = {}
  2282.     jstack = {}
  2283.     isRunning = true
  2284.     parallel.waitForAny( function()
  2285.         local vars = env.vars
  2286.         while true do
  2287.             EVENT = { os.pullEventRaw() }
  2288.             if EVENT[ 1 ] == "terminate" then
  2289.                 return
  2290.             elseif EVENT[ 1 ] == "char" then
  2291.                 vars.keystr = vars.keystr .. EVENT[ 2 ]
  2292.             elseif EVENT[ 1 ] == "key" then
  2293.                 if EVENT[ 2 ] == keys.z then
  2294.                     allEvInputs[ #allEvInputs + 1 ] = {
  2295.                         [ 5 ] = 1;
  2296.                     }
  2297.                 elseif EVENT[ 2 ] == keys.x then
  2298.                     allEvInputs[ #allEvInputs + 1 ] = {
  2299.                         [ 6 ] = 1;
  2300.                     }
  2301.                 elseif EVENT[ 2 ] == keys.left then
  2302.                     allEvInputs[ #allEvInputs + 1 ] = {
  2303.                         [ 1 ] = 1;
  2304.                     }
  2305.                 elseif EVENT[ 2 ] == keys.right then
  2306.                     allEvInputs[ #allEvInputs + 1 ] = {
  2307.                         [ 2 ] = 1;
  2308.                     }
  2309.                 elseif EVENT[ 2 ] == keys.up then
  2310.                     allEvInputs[ #allEvInputs + 1 ] = {
  2311.                         [ 3 ] = 1;
  2312.                     }
  2313.                 elseif EVENT[ 2 ] == keys.down then
  2314.                     allEvInputs[ #allEvInputs + 1 ] = {
  2315.                         [ 4 ] = 1;
  2316.                     }
  2317.                 end
  2318.             elseif EVENT[ 1 ] == "key_up" then
  2319.                 if EVENT[ 2 ] == keys.z then
  2320.                     allEvInputs[ #allEvInputs + 1 ] = {
  2321.                         [ 5 ] = 0;
  2322.                     }
  2323.                 elseif EVENT[ 2 ] == keys.x then
  2324.                     allEvInputs[ #allEvInputs + 1 ] = {
  2325.                         [ 6 ] = 0;
  2326.                     }
  2327.                 elseif EVENT[ 2 ] == keys.left then
  2328.                     allEvInputs[ #allEvInputs + 1 ] = {
  2329.                         [ 1 ] = 0;
  2330.                     }
  2331.                 elseif EVENT[ 2 ] == keys.right then
  2332.                     allEvInputs[ #allEvInputs + 1 ] = {
  2333.                         [ 2 ] = 0;
  2334.                     }
  2335.                 elseif EVENT[ 2 ] == keys.up then
  2336.                     allEvInputs[ #allEvInputs + 1 ] = {
  2337.                         [ 3 ] = 0;
  2338.                     }
  2339.                 elseif EVENT[ 2 ] == keys.down then
  2340.                     allEvInputs[ #allEvInputs + 1 ] = {
  2341.                         [ 4 ] = 0;
  2342.                     }
  2343.                 end
  2344.             end
  2345.         end
  2346.     end, function()
  2347.         local prhl = peripheral.getNames()
  2348.         local doSlp = false
  2349.         while true do
  2350.             doSlp = false
  2351.             for i=1, #prhl do
  2352.                 if peripheral.getType( prhl[ i ] ) == "modem" then
  2353.                     if rednet.isOpen( prhl[ i ] ) then
  2354.                         local id, msg = rednet.receive( "basip" )
  2355.                         msg = simpleParse( msg )
  2356.                         msg[ 1 ] = msg[ 1 ] or ""
  2357.                         msg[ 2 ] = msg[ 2 ] or ""
  2358.                         if msg[ 1 ] == "check_ip" then
  2359.                             if msg[ 2 ] == _CURR_NET_SEND.ip then
  2360.                                 rednet.send( id, "change_ip", "basip" )
  2361.                             end
  2362.                         elseif msg[ 1 ] == "ip" then
  2363.                             if _CURR_NET_SEND.ip == msg[ 2 ] then
  2364.                                 rednet.send( id, _CURR_NET_SEND.ip, "basip" )
  2365.                             end
  2366.                         end
  2367.                     else
  2368.                         doSlp = true
  2369.                     end
  2370.                 else
  2371.                     doSlp = true
  2372.                 end
  2373.             end
  2374.             if doSlp then sleep( .1 ) end
  2375.         end
  2376.     end, function()
  2377.         local prhl = peripheral.getNames()
  2378.         local doSlp = false
  2379.         local lastIP = ""
  2380.         while true do
  2381.             doSlp = false
  2382.             lastIP = ""
  2383.             for i=1, #prhl do
  2384.                 if peripheral.getType( prhl[ i ] ) == "modem" then
  2385.                     if rednet.isOpen( prhl[ i ] ) then
  2386.                         local id, msg = rednet.receive( "bas" )
  2387.                         msg = simpleParse( msg )
  2388.                         if lastIP == msg[ 1 ] then
  2389.                             break
  2390.                         end
  2391.                         _CURR_NET_RECEIVE = {
  2392.                             [ "senderID" ] = id;
  2393.                             [ "senderIP" ] = msg[ 1 ] or "";
  2394.                             [ "senderMsgType" ] = msg[ 2 ] or "";
  2395.                             [ "senderMsg" ] = table.concat( msg, " ", 3 );
  2396.                         }
  2397.                         lastIP = msg[ 1 ]
  2398.                         doSlp = false
  2399.                         break
  2400.                     else
  2401.                         doSlp = true
  2402.                     end
  2403.                 else
  2404.                     doSlp = true
  2405.                 end
  2406.             end
  2407.             if doSlp then sleep( .1 ) end
  2408.         end
  2409.     end, function()
  2410.         local tblRem = table.remove
  2411.         while isRunning == true do
  2412.             local vars = env.vars
  2413.             if #allEvInputs > 0 then
  2414.                 local evs = allEvInputs[ 1 ]
  2415.                 for i=1, 6 do
  2416.                     buttons[ i ] = evs[ i ] or 0
  2417.                 end
  2418.                 tblRem( allEvInputs, 1 )
  2419.             end
  2420.             for _=0, 0xFF do
  2421.                 if isRunning == true then
  2422.                     vars.cycles = _
  2423.                     cycle( fetch(), env )
  2424.                     if highres == true and updated == true then
  2425.                         canvas:draw()
  2426.                         updated = false
  2427.                     end
  2428.                 else
  2429.                     break
  2430.                 end
  2431.             end
  2432.             for i=1, #_timers do
  2433.                 if _timers[ i ] > 0 then
  2434.                     _timers[ i ] = _timers[ i ] - 1
  2435.                 end
  2436.             end
  2437.             _CURR_NET_RECEIVE = {}
  2438.             _CAN_NET_SEND = true
  2439.             queue( "GET_FECH_BAS" )
  2440.             os.pullEventRaw( "GET_FECH_BAS" )
  2441.         end
  2442.     end )
  2443. end
  2444.  
  2445. local function getFileExt( file )
  2446.     for i=#file, 1, -1 do
  2447.         if file:sub( i, i ) == "." then
  2448.             return file:sub( 1, i-1 ), file:sub( i+1, #file )
  2449.         end
  2450.     end
  2451.     return file, ""
  2452. end
  2453.  
  2454. parallel.waitForAny( function()
  2455.     if #tArgs == 3 then
  2456.         if tArgs[ 1 ] == "c" then
  2457.             if fs.exists( tArgs[ 2 ] ) then
  2458.                 local file = fs.open( tArgs[ 2 ], 'r' )
  2459.                 currFile = tArgs[ 2 ]
  2460.                 local bc = compile( file.readAll() )
  2461.                 file.close()
  2462.                 writeBytecodeToFile( tArgs[ 3 ], makeByteTable( bc ) )
  2463.             else
  2464.                 printError( "File "..tArgs[ 2 ].." does not exist!" )
  2465.                 printError( "Usage: BASIC c <in> <out>      -> compile BASIC file" )
  2466.                 printError( "Usage: BASIC r <in>            -> load BASIC bytecode file" )
  2467.                 printError( "Usage: BASIC <filename>        -> run BASIC file" )
  2468.                 printError( "Usage: BASIC                   -> run BASIC shell" )
  2469.                 error()
  2470.             end
  2471.         elseif tArgs[ 1 ] == "m" then
  2472.             if fs.exists( tArgs[ 2 ] ) then
  2473.                 local file = fs.open( tArgs[ 2 ], 'r' )
  2474.                 local bc = compile( file.readAll() )
  2475.                 file.close()
  2476.                 makeRunnableNET( tArgs[ 3 ], makeByteTable( bc ) )
  2477.             end
  2478.         else
  2479.             printError( "Usage: BASIC c <in> <out>      -> compile BASIC file" )
  2480.             printError( "Usage: BASIC r <in>            -> load BASIC bytecode file" )
  2481.             printError( "Usage: BASIC <filename>        -> run BASIC file" )
  2482.             printError( "Usage: BASIC                   -> run BASIC shell" )
  2483.             error()
  2484.         end
  2485.     elseif #tArgs == 2 then
  2486.         if tArgs[ 1 ] == "r" then
  2487.             if fs.exists( tArgs[ 2 ] ) then
  2488.                 currFile = tArgs[ 2 ]
  2489.                 local mem = makeBytecode( readBytecodeFile( tArgs[ 2 ] ) )
  2490.                 _PROGRAM_OFFSET = _PROGRAM_OFFSET + loadToMemory( mem, nil, true )
  2491.                 interpret( Enviroment() )
  2492.             else
  2493.                 printError( "File "..tArgs[ 2 ].." does not exist!" )
  2494.                 printError( "Usage: BASIC c <in> <out>      -> compile BASIC file" )
  2495.                 printError( "Usage: BASIC r <in>            -> load BASIC bytecode file" )
  2496.                 printError( "Usage: BASIC <filename>        -> run BASIC file" )
  2497.                 printError( "Usage: BASIC                   -> run BASIC shell" )
  2498.                 error()
  2499.             end
  2500.         else
  2501.             printError( "Usage: BASIC c <in> <out>      -> compile BASIC file" )
  2502.             printError( "Usage: BASIC r <in>            -> load BASIC bytecode file" )
  2503.             printError( "Usage: BASIC <filename>        -> run BASIC file" )
  2504.             printError( "Usage: BASIC                   -> run BASIC shell" )
  2505.             error()
  2506.         end
  2507.     elseif #tArgs == 1 then
  2508.         if fs.exists( tArgs[ 1 ] ) then
  2509.             local file = fs.open( tArgs[ 1 ], 'r' )
  2510.             currFile = tArgs[ 1 ]
  2511.             local mem = compile( file.readAll() )
  2512.             file.close()
  2513.             _PROGRAM_OFFSET = _PROGRAM_OFFSET + loadToMemory( mem, nil, true )
  2514.             interpret( Enviroment() )
  2515.         else
  2516.             printError( "File "..tArgs[ 1 ].." does not exist!" )
  2517.             printError( "Usage: BASIC c <in> <out>      -> compile BASIC file" )
  2518.             printError( "Usage: BASIC r <in>            -> load BASIC bytecode file" )
  2519.             printError( "Usage: BASIC <filename>        -> run BASIC file" )
  2520.             printError( "Usage: BASIC                   -> run BASIC shell" )
  2521.             error()
  2522.         end
  2523.     elseif #tArgs == 0 then
  2524.         local function sayReady()
  2525.             print()
  2526.             print( "READY" )
  2527.         end
  2528.         local str = "**** ComputerCraft BASIC Version ".._BAS_VER.." ****"
  2529.         setBgCol( colors.blue )
  2530.         setTxtCol( colors.lightBlue )
  2531.         term.clear()
  2532.         term.setCursorPos( math.floor( _w/2-#str/2 ), 1 )
  2533.         write( str );str = "Made by LeDark Lua"
  2534.         term.setCursorPos( math.floor( _w/2-#str/2 ), 2 )
  2535.         write( str )
  2536.         print()
  2537.         currFile = "NEWFILE"
  2538.         local inputedCode = {}
  2539.         local maxLine = 1
  2540.         local env = Enviroment()
  2541.         sayReady()
  2542.         while true do
  2543.             local r = _read()
  2544.             if r == 0xE7D then return end
  2545.             local commands = simpleParse( r )
  2546.             if commands[ 1 ] == "new" then
  2547.                 currFile = "NEWFILE"
  2548.                 maxLine = 1
  2549.                 inputedCode = {}
  2550.                 env = Enviroment()
  2551.                 sayReady()
  2552.             elseif commands[ 1 ] == "run" then
  2553.                 _PROGRAM_OFFSET = 0
  2554.                 local code = ""
  2555.                 for i=1, maxLine do
  2556.                     if inputedCode[ i ] then
  2557.                         code = code .. inputedCode[ i ] .. "\n"
  2558.                     end
  2559.                 end
  2560.                 _PROGRAM_OFFSET = _PROGRAM_OFFSET + loadToMemory( compile( code ), nil, true )
  2561.                 interpret( env )
  2562.                 _w, _h = term.getSize()
  2563.                 sayReady()
  2564.             elseif commands[ 1 ] == "list" then
  2565.                 if commands[ 2 ] == "bc" then
  2566.                     local code = ""
  2567.                     for i=1, maxLine do
  2568.                         if inputedCode[ i ] then
  2569.                             code = code .. inputedCode[ i ] .. "\n"
  2570.                         end
  2571.                     end
  2572.                     loadToMemory( compile( code ) )
  2573.                     local xoff = 1
  2574.                     local i = 1
  2575.                     local check = false
  2576.                     while i <= #memory do
  2577.                         local m = opToName[ memory[ i ] ]
  2578.                         if check == false and m then
  2579.                             if m[ 1 ] == "HALT" then
  2580.                                 check = true
  2581.                             end
  2582.                             local c = m[ 1 ].."( "
  2583.                             local _ = 0
  2584.                             for j=1, m[ 2 ] do
  2585.                                 c = c .. memory[ i+j ].." "
  2586.                                 _ = _ + 1
  2587.                             end
  2588.                             write( c..") " )
  2589.                             i = i + _ + 1
  2590.                         else
  2591.                             write( "MEM[ "..memory[ i ].." ] " )
  2592.                             i = i + 1
  2593.                         end
  2594.                     end
  2595.                     print()
  2596.                 else
  2597.                     local s = commands[ 2 ] or 1
  2598.                     local e = commands[ 3 ] or maxLine
  2599.                     for i=s, e do
  2600.                         if inputedCode[ i ] then
  2601.                             print( inputedCode[ i ] )
  2602.                         end
  2603.                     end
  2604.                 end
  2605.                 sayReady()
  2606.             elseif commands[ 1 ] == "save" then
  2607.                 if commands[ 2 ] then
  2608.                     print( "Saving as: "..commands[ 2 ].."..." )
  2609.                     currFile = commands[ 2 ]
  2610.                     local file = fs.open( commands[ 2 ], 'w' )
  2611.                     for i=1, maxLine do
  2612.                         if inputedCode[ i ] then
  2613.                             file.write( inputedCode[ i ].."\n" )
  2614.                         end
  2615.                     end
  2616.                     file.close()
  2617.                     print( "Saved." )
  2618.                 else
  2619.                     printError( "No file specified!" )
  2620.                 end
  2621.                 sayReady()
  2622.             elseif commands[ 1 ] == "load" then
  2623.                 local sec = commands[ 2 ] or ""
  2624.                 if sec:sub( #sec, #sec ) == "$" then
  2625.                     local dir = sec:sub( 1, #sec-1 )
  2626.                     maxLine = 1
  2627.                     inputedCode = {}
  2628.                     local files = fs.list( dir )
  2629.                     inputedCode[ 1 ] = "FILE NAME                                EXT"
  2630.                     for i=1, #files do
  2631.                         local file, ext = getFileExt( files[ i ] )
  2632.                         if fs.isDir( dir.."/"..files[ i ] ) == true then
  2633.                             ext = "DIR"
  2634.                             table.insert( inputedCode, 2, file..string.rep( " ", 41-#files[ i ] )..ext )
  2635.                         elseif fs.isReadOnly( dir.."/"..files[ i ] ) then
  2636.                             inputedCode[ #inputedCode+1 ] = file..string.rep( " ", 41-#files[ i ] ).."***"
  2637.                         else
  2638.                             inputedCode[ #inputedCode+1 ] = file..string.rep( " ", 41-#files[ i ] )..string.rep( " ", #ext+1 )..ext
  2639.                         end
  2640.                         max.Line = maxLine + 1
  2641.                     end
  2642.                 elseif sec ~= "" then
  2643.                     maxLine = 1
  2644.                     inputedCode = {}
  2645.                     print( "Loading: "..commands[ 2 ].."..." )
  2646.                     if fs.exists( commands[ 2 ] ) then
  2647.                         currFile = commands[ 2 ]
  2648.                         env = Enviroment()
  2649.                         local file = fs.open( commands[ 2 ], 'r' )
  2650.                         local l = 1
  2651.                         while true do
  2652.                             local line = file.readLine()
  2653.                             if line == nil then break end
  2654.                             if line ~= "" then
  2655.                                 line = simpleParse( line )
  2656.                                 if tonumber( line[ 1 ] ) then
  2657.                                     l = tonumber( line[ 1 ] )
  2658.                                 else
  2659.                                     l = l + 1
  2660.                                 end
  2661.                                 if l > maxLine then
  2662.                                     maxLine = l
  2663.                                 end
  2664.                                 inputedCode[ l ] = table.concat( line, " " )
  2665.                             end
  2666.                         end
  2667.                         file.close()
  2668.                         print( "Loaded." )
  2669.                     else
  2670.                         printError( "File doesn't exist!" )
  2671.                     end
  2672.                 else
  2673.                     printError( "No file specified!" )
  2674.                 end
  2675.                 sayReady()
  2676.             elseif commands[ 1 ] == "clear" then
  2677.                 term.setCursorPos( 1, 1 )
  2678.                 term.clear()
  2679.             elseif commands[ 1 ] == "exit" then
  2680.                 return
  2681.             else
  2682.                 if #commands > 1 then
  2683.                     local l = tonumber( commands[ 1 ] )
  2684.                     if type( l ) == "number" then
  2685.                         if l > maxLine then
  2686.                             maxLine = l
  2687.                         end
  2688.                         inputedCode[ l ] = table.concat( commands, " " )
  2689.                     end
  2690.                 end
  2691.             end
  2692.         end
  2693.     else
  2694.         printError( "To many arguments!" )
  2695.         printError( "Usage: BASIC c <in> <out>      -> compile BASIC file" )
  2696.         printError( "Usage: BASIC r <in>            -> load BASIC bytecode file" )
  2697.         printError( "Usage: BASIC <filename>        -> run BASIC file" )
  2698.         printError( "Usage: BASIC                   -> run BASIC shell" )
  2699.         error()
  2700.     end
  2701. end )
  2702. term.setTextColor( colors.white )
  2703. term.setBackgroundColor( colors.black )
  2704. print( "Thanks for using CCBASIC" )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement