Skip to content

Instantly share code, notes, and snippets.

Created July 31, 2015 18:40
Show Gist options
  • Save anonymous/609822a64d04f20008fe to your computer and use it in GitHub Desktop.
Save anonymous/609822a64d04f20008fe to your computer and use it in GitHub Desktop.
CAPL v1.0
# Custom class for errorcodes
class ERR
def self.ERR; -1 end
def self.OK; 0 end
def self.EXIT; 1 end
def self.UNKNOWN; 2 end
def self.EMPTY_STACK; 3 end
def self.get x
case x
when self.ERR; 'ERR'
when self.OK; 'OK'
when self.EXIT; 'EXIT'
when self.UNKNOWN; 'UNKNOWN'
when self.EMPTY_STACK; 'EMPTY_STACK'
end
end
end
# Custom class for stack
class Stack
$mystack=[]
# --- Main functions ---
# Push a new value on the stack
def push x
log "PUSH #{x}"
$mystack.push x
end
# Pop the top value
def pop
log "POP #{$mystack[-1]}"
if $mystack.length == 0
puts "COULD NOT POP: EMPTY STACK"
return [ERR.EMPTY_STACK, "COULD NOT POP"]
end
$mystack.pop
end
# --- Custom functions ---
# Print the stack
def print
$mystack.each.with_index do |item, inx|
# \t[0] 100
puts "\t[#{inx}] #{item}"
end
end
# Get the length from the stack
def length
return $mystack.length
end
# Reverse the array `amount` times
def reverse amount
# Temporary array
temp=[]
# Pop item from current array, and push it to the temp array
amount.times do
temp.push pop
end
# Get first item from temp array, and push it to the current stack
temp.each do |x|
push x
end
# Free temp array
temp=nil
# No need to return anything
end
end
# All global variables
$stack=Stack.new
$loc = {
x: 0,
y: 0
}
$isnumber=false
$number=0
$isstring=false
$string=""
$skip=false
$debug=false
# Output a message when it's given and when debug is on,
# return the debug value if no message is given
def log message=nil
return $debug if message==nil
puts "\t#{message}" if $debug
end
# Load a custom framework
def load type
begin
# FileIO; custom library to load and read files
if type=="FileIO"
# Load the file
require '~/Ruby Frameworks/FileIO.rb'
# Check if it works
log FileIO.check
else
throw "Type unknown"
end
# When we failed to load framework
rescue Exception => e
puts "Failed to load #{type}!"
raise e
end
end
# Parse the current character
def parse char
# If we expect a number, and the character isn't ']'
if $isnumber && char != ']'
# Check if it really is a number
if char=~/^[0-9]+$/
# Add the new number to the global number
$number*=10
$number+=char.ord - '0'.ord
# Return OK value
return [ERR.OK]
# If it isn't a number
else
puts "'#{$char}' is not a number, but is between square brackets [] !"
end
end
# If we expect a string, and the character isn't '"'
if $isstring && char != '"'
# Add the character to the current string
$string+=char
# Return OK value
return [ERR.OK]
end
# If the character is a null character (what ?!) or a space
if char==0 || char==' '
# If we have to skip ( After ? or ! )
elsif $skip
log "SKIP"
$skip=false
# Return OK value
return [ERR.OK]
# Number
elsif char=='['
$isnumber=true
elsif char==']'
$isnumber=false
$stack.push $number
$number=0
# Check for single hexadecimal number
elsif char=~/[0-9a-f]/
x=char.to_i 16
$stack.push x
# String
elsif char=='"'
# If we don't expect a string ...
if ! $isstring
# ... we do now
$isstring=true
# ... but if we do ...
else
# ... we don't now
$isstring=false
# And add the global string in ASCII to the stack
$string.split('').each do |c|
$stack.push c.ord
end
# Reset global string
$string=""
end
# Output
# Output as number
elsif char==','
log "NUMBER OUT"
print $stack.pop
log ""
# Output as ASCII
elsif char=='.'
log "CHAR OUT"
print $stack.pop.chr
puts if log
# Output the stack
elsif char=='P'
log "PRINT"
$stack.print
# Manipulation
# Reverse `x` items
elsif char=='~'
log "REVERSE #{x=$stack.pop}"
$stack.reverse x
# Copy top value
elsif char==':'
log "COPY"
x=$stack.pop
$stack.push x
$stack.push x
# Add, subtract, multiplicate, devide and modulus
elsif char=~/[\+\-\*\/\%]/
log "EXPR #{char}"
y=$stack.pop
x=$stack.pop
# Eval is safe here
z=eval("#{x}#{char}#{y}")
$stack.push z
# Get length
elsif char=='#'
log "LENGTH"
x=$stack.length
$stack.push x
# Go back to the start of the line
elsif char=='<'
log "HOME"
$loc[:x]=-1
# Go `x` lines down
elsif char=='v'
log "DOWN"
x=$stack.pop
$loc[:x]=-1
$loc[:y]+=x
# Go `x` lines up
elsif char=='^'
log "UP"
x=$stack.pop
$loc[:x]=-1
$loc[:y]-=x
# Contitional. Go 1 to the right if `x` is not 0, or 2 to the right if it is
elsif char=='?'
log "COND"
x=$stack.pop
if x==0
$skip=true
end
# Skip the following character
elsif char=='!'
log "SKIP"
$skip=true
# Delete top value
elsif char=='x'
log "DELETE"
$stack.pop
# Exit file
elsif char==';'
return [ERR.EXIT]
# If we have NO idea what we have to do, just throw an error
else
return [ERR.UNKNOWN, char]
end
return [ERR.OK]
end
# Explode an array
def explode pre
# New array
post=[]
# Split each string from `pre` into its characters
pre.each.with_index do |item, inx|
post[inx] = item.split ''
end
# New array
post
end
# Get the character at the current position
def get
$content [ $loc[:y] ] [ $loc[:x] ]
end
def main args
# No arguments enables debug mode
if args.count == 0
$debug=true
log "Debug enabled!"
end
# Setting filename
filename=args[0] || "debug.cpl"
log "Filename: #{filename}"
# Loading FileIO to load files
load "FileIO"
# Loading FileIO for current file
fio=FileIO.new "#{filename}"
# Convert 2D array to 3D array
# ['abc', 'def'] => [['a','b','c'], ['d','e','f']]
$content=explode fio.getContent
# Logging content if debug mode enabled
if log
puts "Content:"
$content.each do |line|
# Two tabs
print "\t\t"
# Outputting each line
line.each do |char|
print char
end
# Newline
puts
end
# Newline
puts
end
# While we don't have to exit
while x[0] != ERR.EXIT
# Log the character
log "'#{get}'"
# Default errorcode
x=ERR.ERR
begin
# Parsing current character
x=parse get
# When error happens
rescue Exception => e
# Print location and character
puts "(#{$loc[:x]},#{$loc[:y]}) '#{get}'"
# Print default stacktrace
raise e
end
# If it didn't run correctly
if x[0] != ERR.OK
# Output location, character, errorcode and errormessage
puts "(#{$loc[:x]},#{$loc[:y]}) '#{get}' #{ERR.get x[0]}: '#{x[1]}'"
end
# Next character
$loc[:x]+=1
end
end
# Start with arguments
main ARGV
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment