Fully remove Clojure and Io. Use new Aether 0.5.0.

This commit is contained in:
Nick Winter 2016-05-24 12:00:04 -07:00
parent 2ded5ff4f0
commit 8fce97aad3
18 changed files with 36 additions and 126 deletions

View file

@ -238,10 +238,8 @@ codeLanguages =
javascript: 'ace/mode/javascript'
coffeescript: 'ace/mode/coffee'
python: 'ace/mode/python'
clojure: 'ace/mode/clojure'
lua: 'ace/mode/lua'
java: 'ace/mode/java'
io: 'ace/mode/text'
class CodeLanguagesObjectTreema extends TreemaNode.nodeMap.object
childPropertiesAvailable: ->

View file

@ -267,9 +267,7 @@ module.exports.aceEditModes = aceEditModes =
'coffeescript': 'ace/mode/coffee'
'python': 'ace/mode/python'
'java': 'ace/mode/java'
'clojure': 'ace/mode/clojure'
'lua': 'ace/mode/lua'
'io': 'ace/mode/text'
'java': 'ace/mode/java'
module.exports.initializeACE = (el, codeLanguage) ->
@ -294,13 +292,9 @@ module.exports.initializeACE = (el, codeLanguage) ->
session.setNewLineMode 'unix'
return editor
module.exports.capitalLanguages = capitalLanguages =
module.exports.capitalLanguages = capitalLanguages =
'javascript': 'JavaScript'
'coffeescript': 'CoffeeScript'
'python': 'Python'
'java': 'Java'
'clojure': 'Clojure'
'lua': 'Lua'
'io': 'Io'

View file

@ -126,8 +126,7 @@ module.exports = class LevelLoader extends CocoClass
@sessionResource = @supermodel.loadModel(session, 'level_session', {cache: false})
@session = @sessionResource.model
if @opponentSessionID
opponentURL = "/db/level.session/#{@opponentSessionID}"
opponentURL += "?interpret=true" if @spectateMode or utils.getQueryVariable 'esper'
opponentURL = "/db/level.session/#{@opponentSessionID}?interpret=true"
opponentSession = new LevelSession().setURL opponentURL
opponentSession.project = session.project if @headless
@opponentSessionResource = @supermodel.loadModel(opponentSession, 'opponent_session', {cache: false})
@ -158,6 +157,8 @@ module.exports = class LevelLoader extends CocoClass
code[if session.get('team') is 'humans' then 'hero-placeholder' else 'hero-placeholder-1'].plan = uncompressed
session.set 'code', code
session.unset 'interpret'
if session.get('codeLanguage') in ['io', 'clojure']
session.set 'codeLanguage', 'python'
if session is @session
@addSessionBrowserInfo session
# hero-ladder games require the correct session team in level:loaded

View file

@ -7,14 +7,6 @@ module.exports.createAetherOptions = (options) ->
throw new Error 'Specify a function name to create an Aether instance' unless options.functionName
throw new Error 'Specify a code language to create an Aether instance' unless options.codeLanguage
useInterpreter = options.useInterpreter
defaultToEsper = true #switch options.codeLanguage
# when 'python' then me.level() < 15 # Esper currently works well until using range()
# when 'javascript' then me.level() < 22 # Esper currently works well until using hero.myFn = function() pattern
# when 'lua' then me.level() < 10 # Functions don't work in Esper yet, can't play forest function levels
# when 'coffeescript' then false # CoffeeScript has a toNative error if it ever finishes plan(), and also @fn = -> pattern doesn't work
# when 'clojure' then false # No Clojure support
useInterpreter ?= !!utils.getQueryVariable 'esper', defaultToEsper
aetherOptions =
functionName: options.functionName
protectAPI: not options.skipProtectAPI
@ -37,7 +29,7 @@ module.exports.createAetherOptions = (options) ->
#functionParameters: # TODOOOOO
executionLimit: 3 * 1000 * 1000
language: options.codeLanguage
useInterpreter: useInterpreter
useInterpreter: true
parameters = functionParameters[options.functionName]
unless parameters
console.warn "Unknown method #{options.functionName}: please add function parameters to lib/aether_utils.coffee."

View file

@ -443,7 +443,7 @@ module.exports = class Simulator extends CocoClass
aether.transpile ''
createAether: (methodName, method, useProtectAPI, codeLanguage) ->
aetherOptions = createAetherOptions functionName: methodName, codeLanguage: codeLanguage, skipProtectAPI: not useProtectAPI, useInterpreter: true
aetherOptions = createAetherOptions functionName: methodName, codeLanguage: codeLanguage, skipProtectAPI: not useProtectAPI
return new Aether aetherOptions
class SimulationTask

View file

@ -645,9 +645,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
python_blurb: "Simple yet powerful, great for beginners and experts."
javascript_blurb: "The language of the web. (Not the same as Java.)"
coffeescript_blurb: "Nicer JavaScript syntax."
clojure_blurb: "A modern Lisp."
lua_blurb: "Game scripting language."
io_blurb: "Simple but obscure."
java_blurb: "(Subscriber Only) Android and enterprise."
status: "Status"
hero_type: "Type"

View file

@ -20,7 +20,7 @@ defaultTasks = [
'Choose music file in Introduction script.'
'Choose autoplay in Introduction script.'
'Add Clojure/Lua/CoffeeScript.'
'Add Lua/CoffeeScript/Java.'
'Write the description.'
'Write the guide.'

View file

@ -36,8 +36,7 @@ require 'vendor/aether-javascript'
require 'vendor/aether-python'
require 'vendor/aether-coffeescript'
require 'vendor/aether-lua'
require 'vendor/aether-clojure'
require 'vendor/aether-io'
require 'vendor/aether-java'
module.exports = class LevelEditView extends RootView
id: 'editor-level-view'
@ -113,7 +112,7 @@ module.exports = class LevelEditView extends RootView
@insertSubView new ComponentsDocumentationView lazy: true # Don't give it the supermodel, it'll pollute it!
@insertSubView new SystemsDocumentationView lazy: true # Don't give it the supermodel, it'll pollute it!
@insertSubView new LevelFeedbackView level: @level
Backbone.Mediator.publish 'editor:level-loaded', level: @level
@showReadOnly() if me.get('anonymous')

View file

@ -21,8 +21,6 @@ module.exports = class SimulateTabView extends CocoView
require 'vendor/aether-coffeescript'
require 'vendor/aether-lua'
require 'vendor/aether-java'
require 'vendor/aether-clojure'
require 'vendor/aether-io'
onLoaded: ->
super()

View file

@ -225,10 +225,7 @@ module.exports = class PlayLevelView extends RootView
opponentSpells = opponentSpells.concat spells
if (not @session.get('teamSpells')) and @otherSession?.get('teamSpells')
@session.set('teamSpells', @otherSession.get('teamSpells'))
if @getQueryVariable 'esper'
opponentCode = @otherSession?.get('code') or {}
else
opponentCode = @otherSession?.get('transpiledCode') or {}
opponentCode = @otherSession?.get('code') or {}
myCode = @session.get('code') or {}
for spell in opponentSpells
[thang, spell] = spell.split '/'
@ -363,15 +360,6 @@ module.exports = class PlayLevelView extends RootView
onLevelStarted: ->
return unless @surface?
#TODO: Remove this at some point
if @session.get('codeLanguage') in ['clojure', 'io']
problem =
aetherProblem:
message: "Sorry, support for #{@session.get('codeLanguage')} has been removed."
Backbone.Mediator.publish 'tome:show-problem-alert', problem: problem
@loadingView.showReady()
@trackLevelLoadEnd()
if window.currentModal and not window.currentModal.destroyed and window.currentModal.constructor isnt VictoryModal
@ -429,16 +417,14 @@ module.exports = class PlayLevelView extends RootView
perhapsStartSimulating: ->
return unless @shouldSimulate()
return console.error "Should not auto-simulate until we fix how these languages are loaded"
# TODO: how can we not require these as part of /play bundle?
#require "vendor/aether-#{codeLanguage}" for codeLanguage in ['javascript', 'python', 'coffeescript', 'lua', 'clojure', 'io']
require 'vendor/aether-javascript'
require 'vendor/aether-python'
require 'vendor/aether-coffeescript'
require 'vendor/aether-lua'
require 'vendor/aether-java'
require 'vendor/aether-clojure'
require 'vendor/aether-io'
require 'vendor/aether-java'
##require "vendor/aether-#{codeLanguage}" for codeLanguage in ['javascript', 'python', 'coffeescript', 'lua', 'java']
#require 'vendor/aether-javascript'
#require 'vendor/aether-python'
#require 'vendor/aether-coffeescript'
#require 'vendor/aether-lua'
#require 'vendor/aether-java'
@simulateNextGame()
simulateNextGame: ->

View file

@ -57,23 +57,18 @@ module.exports = class DocFormatter
else (if @options.useHero then 'hero' else 'this')
if @doc.type is 'function'
[docName, args] = @getDocNameAndArguments()
sep = {clojure: ' '}[@options.language] ? ', '
argNames = args.join sep
argNames = args.join ', '
argString = if argNames then '__ARGS__' else ''
@doc.shortName = switch @options.language
when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{docName}#{if argString then ' ' + argString else '()'}"
when 'python' then "#{ownerName}.#{docName}(#{argString})"
when 'lua' then "#{ownerName}:#{docName}(#{argString})"
when 'clojure' then "(.#{docName} #{ownerName}#{if argNames then ' ' + argString else ''})"
when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{docName}#{if argNames then '(' + argNames + ')' else ''}"
else "#{ownerName}.#{docName}(#{argString});"
else
@doc.shortName = switch @options.language
when 'coffeescript' then "#{ownerName}#{if ownerName is '@' then '' else '.'}#{@doc.name}"
when 'python' then "#{ownerName}.#{@doc.name}"
when 'lua' then "#{ownerName}.#{@doc.name}"
when 'clojure' then "(.#{@doc.name} #{ownerName})"
when 'io' then "#{if ownerName is 'this' then '' else ownerName + ' '}#{@doc.name}"
else "#{ownerName}.#{@doc.name};"
@doc.shorterName = @doc.shortName
if @doc.type is 'function' and argString
@ -89,7 +84,7 @@ module.exports = class DocFormatter
translatedName = utils.i18n(@doc, 'name')
if translatedName isnt @doc.name
@doc.translatedShortName = @doc.shortName.replace(@doc.name, translatedName)
# Grab the language-specific documentation for some sub-properties, if we have it.
toTranslate = [{obj: @doc, prop: 'description'}, {obj: @doc, prop: 'example'}]
@ -153,16 +148,12 @@ module.exports = class DocFormatter
when 'coffeescript' then "loop"
when 'python' then "while True:"
when 'lua' then "while true do"
when 'clojure' then "(while true)"
when 'io' then "while(true)"
else "while (true)"
for field in ['example', 'description']
[simpleLoop, whileLoop] = switch @options.language
when 'coffeescript' then [/loop/g, "loop"]
when 'python' then [/loop:/g, "while True:"]
when 'lua' then [/loop/g, "while true do"]
when 'clojure' then [/\(dotimes( \[n \d+\])?/g, "(while true"]
when 'io' then [/loop\(/g, "while(true,"]
else [/loop/g, "while (true)"]
@doc[field] = @doc[field].replace simpleLoop, whileLoop

View file

@ -33,12 +33,8 @@ module.exports = class Spell
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
if @canWrite()
@setLanguage options.language
else if @isEnemySpell()
@setLanguage @otherSession?.get('submittedCodeLanguage') ? @spectateOpponentCodeLanguage
else
@setLanguage 'javascript'
@useTranspiledCode = @shouldUseTranspiledCode()
#console.log 'Spell', @spellKey, 'is using transpiled code (should only happen if it\'s an enemy/spectate writable method).' if @useTranspiledCode
@source = @originalSource
@parameters = p.parameters
@ -88,10 +84,8 @@ module.exports = class Spell
@originalSource = switch @language
when 'python' then @originalSource.replace /loop:/, 'while True:'
when 'javascript' then @originalSource.replace /loop {/, 'while (true) {'
when 'clojure' then @originalSource.replace /dotimes \[n 1000\]/, '(while true'
when 'lua' then @originalSource.replace /loop\n/, 'while true then\n'
when 'coffeescript' then @originalSource
when 'io' then @originalSource.replace /loop\n/, 'while true,\n'
else @originalSource
addPicoCTFProblem: ->
@ -126,15 +120,10 @@ module.exports = class Spell
else
source = @getSource()
[pure, problems] = [null, null]
if @useTranspiledCode
transpiledCode = @session.get('code')
for thangID, spellThang of @thangs
unless pure
if @useTranspiledCode and transpiledSpell = transpiledCode[@spellKey.split('/')[0]]?[@name]
spellThang.aether.pure = transpiledSpell
else
pure = spellThang.aether.transpile source
problems = spellThang.aether.problems
pure = spellThang.aether.transpile source
problems = spellThang.aether.problems
#console.log 'aether transpiled', source.length, 'to', spellThang.aether.pure.length, 'for', thangID, @spellKey
else
spellThang.aether.raw = source
@ -182,7 +171,7 @@ module.exports = class Spell
skipProtectAPI: skipProtectAPI
includeFlow: includeFlow
problemContext: problemContext
useInterpreter: if @spectateView then true else undefined
useInterpreter: true
aether = new Aether aetherOptions
if @worker
workerMessage =
@ -207,22 +196,6 @@ module.exports = class Spell
toString: ->
"<Spell: #{@spellKey}>"
isEnemySpell: ->
return false unless @permissions.readwrite.length
return false unless @otherSession or @spectateView
teamSpells = @session.get('teamSpells')
team = @session.get('team') ? 'humans'
teamSpells and not _.contains(teamSpells[team], @spellKey)
shouldUseTranspiledCode: ->
# Determine whether this code has already been transpiled, or whether it's raw source needing transpilation.
return false if @spectateView or utils.getQueryVariable 'esper' # Don't use transpiled code with interpreter
return true if @isEnemySpell() # Use transpiled for enemy spells.
# Players without permissions can't view the raw code.
return false if @observing and @levelType in ['hero', 'course']
return true if @session.get('creator') isnt me.id and not (me.isAdmin() or 'employer' in me.get('permissions', true))
false
createProblemContext: (thang) ->
# Create problemContext Aether can use to craft better error messages
# stringReferences: values that should be referred to as a string instead of a variable (e.g. "Brak", not Brak)

View file

@ -46,10 +46,6 @@ module.exports = class SpellListEntryView extends CocoView
paramString = parameters.join ', '
name = @spell.name
switch @spell.language
when 'io'
"#{name} := method(#{paramString})"
when 'clojure'
"(defn #{name} [#{paramString}] ...)"
when 'python'
"def #{name}(#{paramString}):"
when 'lua'

View file

@ -230,7 +230,7 @@ module.exports = class SpellView extends CocoView
disableSpaces = @options.level.get('disableSpaces') or false
aceConfig = me.get('aceConfig') ? {}
disableSpaces = false if aceConfig.keyBindings and aceConfig.keyBindings isnt 'default' # Not in vim/emacs mode
disableSpaces = false if @spell.language in ['clojure', 'lua', 'java', 'coffeescript', 'io'] # Don't disable for more advanced/experimental languages
disableSpaces = false if @spell.language in ['lua', 'java', 'coffeescript'] # Don't disable for more advanced/experimental languages
if not disableSpaces or (_.isNumber(disableSpaces) and disableSpaces < me.level())
return @ace.execCommand 'insertstring', ' '
line = @aceDoc.getLine @ace.getCursorPosition().row
@ -301,7 +301,10 @@ module.exports = class SpellView extends CocoView
for row in [0..@aceSession.getLength()]
foldWidgets[row] = @aceSession.getFoldWidget(row) unless foldWidgets[row]?
continue unless foldWidgets? and foldWidgets[row] is "start"
docRange = @aceSession.getFoldWidgetRange(row)
try
docRange = @aceSession.getFoldWidgetRange(row)
catch error
console.warn "Couldn't find fold widget docRange for row #{row}:", error
if not docRange?
guess = startOfRow(row)
docRange = new Range(row,guess,row,guess+4)
@ -520,10 +523,8 @@ module.exports = class SpellView extends CocoView
content = switch e.language
when 'python' then content.replace /loop:/, 'while True:'
when 'javascript' then content.replace /loop/, 'while (true)'
when 'clojure' then content.replace /dotimes \[n 1000\]/, '(while true'
when 'lua' then content.replace /loop/, 'while true then'
when 'coffeescript' then content
when 'io' then content.replace /loop/, 'while true,'
else content
name = switch e.language
when 'python' then 'while True'
@ -557,9 +558,8 @@ module.exports = class SpellView extends CocoView
if doc.userShouldCaptureReturn
varName = doc.userShouldCaptureReturn.variableName ? 'result'
entry.captureReturn = switch e.language
when 'io' then varName + ' := '
when 'javascript' then 'var ' + varName + ' = '
when 'clojure' then '(let [' + varName + ' '
#when 'lua' then 'local ' + varName + ' = ' # TODO: should we do this?
else varName + ' = '
# TODO: Generalize this snippet replacement
@ -583,15 +583,8 @@ module.exports = class SpellView extends CocoView
translateFindNearest: ->
# If they have advanced glasses but are playing a level which assumes earlier glasses, we'll adjust the sample code to use the more advanced APIs instead.
oldSource = @getSource()
if @spell.language is 'clojure'
newSource = oldSource.replace /\(.findNearestEnemy this\)/g, "(.findNearest this (.findEnemies this))"
newSource = newSource.replace /\(.findNearestItem this\)/g, "(.findNearest this (.findItems this))"
else if @spell.language is 'io'
newSource = oldSource.replace /findNearestEnemy/g, "findNearest(findEnemies)"
newSource = newSource.replace /findNearestItem/g, "findNearest(findItems)"
else
newSource = oldSource.replace /(self:|self.|this.|@)findNearestEnemy\(\)/g, "$1findNearest($1findEnemies())"
newSource = newSource.replace /(self:|self.|this.|@)findNearestItem\(\)/g, "$1findNearest($1findItems())"
newSource = oldSource.replace /(self:|self.|this.|@)findNearestEnemy\(\)/g, "$1findNearest($1findEnemies())"
newSource = newSource.replace /(self:|self.|this.|@)findNearestItem\(\)/g, "$1findNearest($1findItems())"
return if oldSource is newSource
@spell.originalSource = newSource
@updateACEText newSource
@ -640,7 +633,7 @@ module.exports = class SpellView extends CocoView
return if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder'] # We'll turn this on later, maybe, but not yet.
@debugView = new SpellDebugView ace: @ace, thang: @thang, spell:@spell
@$el.append @debugView.render().$el.hide()
createTranslationView: ->
@translationView = new SpellTranslationView { @ace, @supermodel }
@$el.append @translationView.render().$el.hide()
@ -731,7 +724,7 @@ module.exports = class SpellView extends CocoView
# Uncomment the below line for a debug panel to display inside the level
#@spade.debugPlay(spadeEvents)
condensedEvents = @spade.condense(spadeEvents)
return unless condensedEvents.length
compressedEvents = LZString.compressToUTF16(JSON.stringify(condensedEvents))
@ -746,7 +739,7 @@ module.exports = class SpellView extends CocoView
})
codeLog.save()
onShowVictory: (e) ->
if @saveSpadeTimeout?
window.clearTimeout @saveSpadeTimeout
@ -1067,12 +1060,8 @@ module.exports = class SpellView extends CocoView
return unless @ace.isFocused() and e.x? and e.y?
if @spell.language is 'python'
@ace.insert "{\"x\": #{e.x}, \"y\": #{e.y}}"
else if @spell.language is 'clojure'
@ace.insert "{:x #{e.x} :y #{e.y}}"
else if @spell.language is 'lua'
@ace.insert "{x=#{e.x}, y=#{e.y}}"
else if @spell.language is 'io'
return
else
@ace.insert "{x: #{e.x}, y: #{e.y}}"
@ -1355,6 +1344,5 @@ commentStarts =
javascript: '//'
python: '#'
coffeescript: '#'
clojure: ';'
lua: '--'
io: '//'
java: '//'

View file

@ -129,7 +129,5 @@ commentStarts =
javascript: '// '
python: '# '
coffeescript: '# '
clojure: '; '
lua: '-- '
io: '// '
java: '// '

View file

@ -32,7 +32,7 @@
"firepad": "~0.1.2",
"marked": "~0.3.0",
"moment": "~2.5.0",
"aether": "~0.4.5",
"aether": "~0.5.0",
"underscore.string": "~2.3.3",
"firebase": "~1.0.2",
"d3": "~3.4.4",

View file

@ -110,9 +110,7 @@ exports.config =
'javascripts/lodash.js': regJoin('^bower_components/lodash/dist/lodash.js')
'javascripts/aether.js': regJoin('^bower_components/aether/build/aether.js')
'javascripts/esper.js': 'bower_components/esper.js/esper.js'
'javascripts/app/vendor/aether-clojure.js': 'bower_components/aether/build/clojure.js'
'javascripts/app/vendor/aether-coffeescript.js': 'bower_components/aether/build/coffeescript.js'
'javascripts/app/vendor/aether-io.js': 'bower_components/aether/build/io.js'
'javascripts/app/vendor/aether-javascript.js': 'bower_components/aether/build/javascript.js'
'javascripts/app/vendor/aether-lua.js': 'bower_components/aether/build/lua.js'
'javascripts/app/vendor/aether-java.js': 'bower_components/aether/build/java.js'

View file

@ -53,7 +53,7 @@
"dependencies": {
"JQDeferred": "~2.1.0",
"ace-builds": "https://github.com/ajaxorg/ace-builds/archive/3fb55e8e374ab02ce47c1ae55ffb60a1835f3055.tar.gz",
"aether": "~0.4.5",
"aether": "~0.5.0",
"async": "0.2.x",
"aws-sdk": "~2.0.0",
"bayesian-battle": "0.0.7",