lfs = require 'lfs' utf8 = require 'utf8' moon = require 'moonscript.base' { graphics: lg } = love trace = (msg) -> debug.traceback msg, 2 class Script new: (file='scratch.moon') => @file = "library/#{file}" @last_modification = 0 @func = -> commit: => export COMMIT COMMIT = true return unless @func ok, msg = xpcall @func, trace, STATE.root if not ok @error = at: 'commit', :msg return COMMIT = false reload_and_run: => func = @reload! @func = func if func ok, msg = xpcall @func, trace, STATE.root if not ok @error = at: 'exec', :msg @print_error! print_error: => if @error switch @error.at when 'parse' do print "--- ERROR PARSING SCRIPT #{@file} ---" when 'load' do print "--- ERROR LOADING SCRIPT: #{@file} ---" when 'exec' do print "--- ERROR EXECUTING SCRIPT: #{@file} ---" when 'commit' do print "--- ERROR COMMITTING SCRIPT: #{@file} ---" print @error.msg reload: => { :mode, :modification } = (lfs.attributes @file) or {} if mode != 'file' @error = at: 'parse', msg: "script doesn't exist or is not a file: '#{@file}'" return if @last_modification < modification @last_modification = modification module, msg = if @file\match '%.moon$' then moon.loadfile @file else loadfile @file if not module @error = at: 'parse', :msg return ok, msg = xpcall module, trace if not msg @error = at: 'load', :msg return @error = nil msg import Object from require 'object' class Session FONTSIZE = 20 new: (scriptfile) => @objects = {} if scriptfile @script = Script scriptfile @font = lg.newFont 'font/FantasqueSansMono-Regular.ttf', 20 @ex = false exec: (command) => switch command\match '^(%w+)' when 'quit' love.event.quit! when 'run' arg = command\match '^run%s+(.+)' @script = Script arg frame: => lg.setColor 1, 1, 1 for obj in *@objects obj\draw! if INPUT\key_down 'escape' STATE\reset! w,h = lg.getDimensions! lg.setFont @font if @script lg.setColor .5, .5, .5 depth = lg.getStackDepth! @script\reload_and_run! if INPUT\key_down 'space' @script\commit! STATE\reset! while lg.getStackDepth! > depth lg.pop! lg.setColor 1, 1, 1 lg.print "script: #{@script.file}", 10, 10 if (INPUT\key_down ':') or (INPUT\key_down ';') and INPUT\key_held 'lshift' INPUT\text_capture! @ex = true if @ex lg.setColor 1, 1, 1 lg.print ":#{INPUT.text}", 10, h - 10 - FONTSIZE apply = INPUT\key_down 'return' input = if apply or INPUT\key_down 'escape' @ex = nil apply and @exec INPUT\text_release! @exec input if input { :Script :Session }