This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Mendax's profile picture

SKS-BASIC

Started by Mendax, 19 December 2012 - 09:46 PM
Mendax #1
Posted 19 December 2012 - 10:46 PM
Now, about six months ago, I wrote an assembler for a language I called 'SScript'. It used single line commands (with arguments!) but it was still just an assembler. Then, I forgot about it for around four months. While cleaning out my Dropbox I found a copy of it. This got me interested again. I had also been playing with a Commodore 64 emulator at the time. I tried my hand at making another assembler. It used multiple lines for commands and was also given the name 'SScript' and published. Then I tried writing an interpreter inside Lua - it turned out just as bad as the previous one. Then, about a week ago, when my holidays started, I started writing a proper BASIC interpreter. It has the BASICs - GOTO, IF and PRINT.

Code:
Spoiler

tArgs = {...}
	
--Extract from StrUtils by tomass1996 of computercraft.info
--Link: http://www.computercraft.info/forums2/index.php?/topic/42-cc13string-utils-api/
	function find(str, match, startIndex)  --Finds @match in @str optionally after @startIndex
			if not match then return nil end
			str = tostring(str)
			local _ = startIndex or 1
			local _s = nil
			local _e = nil
			local _len = match:len()
			while true do
					local _t = str:sub( _ , _len + _ - 1)
					if _t == match then
							_s = _
							_e = _ + _len - 1
							break
					end
					_ = _ + 1
					if _ > str:len() then break end
			end
			if _s == nil then return nil else return _s, _e end
	end
	function seperate(str, divider)  --Separates @str on @divider
			if not divider then return nil end
			str = tostring(str)
			local start = {}
			local endS = {}
			local n=1
			repeat
					if n==1 then
							start[n], endS[n] = find(str, divider)
					else
							start[n], endS[n] = find(str, divider, endS[n-1]+1)
			end
					n=n+1
			until start[n-1]==nil
			local subs = {}
			for n=1, #start+1 do
					if n==1 then
							subs[n] = str:sub(1, start[n]-1)
					elseif n==#start+1 then
							subs[n] = str:sub(endS[n-1]+1)
					else
							subs[n] = str:sub(endS[n-1]+1, start[n]-1)
			end
			end
			return subs
	end
	
	--Now, my stuff - this is the function that reads a file into a table
	function readFileLines(filename)
	 file = fs.open(filename,"r")
	 local tLines = {}
	 repeat
	  line = file.readLine()
	  table.insert(tLines,line)
	 until line == nil
	 file.close()
	 return tLines
	end
	
	--And this - this is the interpreter
	function runFile(runfilename)
	 local lines = readFileLines(runfilename)
	 local number = 1
	 repeat
	  line = seperate(lines[number]," ")
	  if line[1] == "PRINT" then
	   num = 2
	   repeat
		write(line[num].." ")
		num = num+1
	   until line[num] == nil
	   print " "
	  elseif line[1] == "DISPLAY" then loadstring("print("..line[2]..")")()
	  elseif line[1] == "GOTO" then setnum = tonumber(line[2]) number = setnum numchanged = true
	  elseif line[1] == "WAIT" then sleep(tonumber(line[2]))
	  elseif line[2] == "=" then loadstring(line[1].." = "..line[3])()
	  elseif line[1] == "INPUT" then loadstring(line[2].." = read()")()
	  elseif line[1] == "IF" and line[5] == "GOTO" then
	   local n = loadstring("if "..line[2].." "..line[3].." "..line[4].." then return "..tonumber(line[6]).." end")()
	  
		if n then
			number = n
			numchanged = true
		end
	  end
	  if numchanged ~= true then number = number+1
	  else numchanged = false
	  end
	 until lines[number] == nil
	end
runFile(tArgs[1])

Installation:
SpoilerJust run 'pastebin get nrLUcLBQ SKS-BASIC'

It is currently VERY buggy and VERY alpha… Current bugs:
SpoilerNote: To display a variable currently write 'DISPLAY VARIABLENAME' Fixed it
License Stuff:
SpoilerThis project is open-source and has been written from scratch. The only thing required is some credit to 'Shadow' which is me and leave in the little bit about the StrUtils extract in there.
Mendax #2
Posted 20 December 2012 - 10:20 AM
This will be the changelog.
Right now, I am adding multithreaded support - run two programs at once (one line of each at a time while switching, sorta like parallel…)