Mercurial > repos > tabletprog
view src/editor.tp @ 251:2557ce4e671f
Fix a couple of compiler bugs. topenv was getting initialized in multiple places. This resulted in multiple copies of modules getting created which caused problems for macro expansion. Additionally, arguments were not being marked as declared during code generation so assigning to an argument that was not closed over generated invalid C code.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 11 Apr 2014 22:29:32 -0700 |
parents | 15aac5334b64 |
children |
line wrap: on
line source
#{ //mquery functions q <- foreign: :query {} qall <- foreign: :query {} each <- foreign: :iterable fun {} addClass <- foreign: :node className {} removeClass <- foreign: :node className {} hasClass <- foreign: :node className {} get <- foreign: :url onSuccess onFail onOther {} newEl <- foreign: :tagname props {} //editor.js functions getEl <- foreign: :from idx {} setEl <- foreign: :to idx val {} goFullScreen <- foreign: {} create_symbol <- foreign: :name {} //TP Parser parser <- foreign: #{ parse <- foreign: :str {} } isLambda <- foreign: :astnode {} //js builtins console <- foreign: #{ log <- foreign: :val {} } window <- foreign: #{} Object <- foreign: #{ keys <- foreign: :object {} } filter <- :arr pred { output <- arr slice: 0 0 each: arr :idx el { if: (pred: el) { output push: el } else: {} } output } //editor code selection <- #{ valid? <- false } setSelection:withInNode <- :astnode :innode { fakeEvent <- #{ stopPropagation <- :Blah { } } selection <- #{ valid? <- true in <- { (innode domNode) onclick: fakeEvent } out <- { ((astnode up) domNode) onclick: fakeEvent } next <- { (((astnode up) getNext: astnode) domNode) onclick: fakeEvent } previous <- { (((astnode up) getPrev: astnode) domNode) onclick: fakeEvent } } } setSelection <- :astnode { fakeEvent <- #{ stopPropagation <- :Blah { } } selection <- #{ valid? <- true in <- { } out <- { fakeEvent <- #{ stopPropagation <- :Blah { } } ((astnode up) domNode) onclick: fakeEvent } next <- { console log: "selection next" (((astnode up) getNext: astnode) domNode) onclick: fakeEvent } previous <- { (((astnode up) getPrev: astnode) domNode) onclick: fakeEvent } } } editFile <- :path { get: path :request { addClass: (q: "body") "editorMode" src <- request responseText ast <- parser parse: src ast populateSymbols: (foreign: null) ast toHTML: (q: "#src") } } selectNode <- :node { each: (qall: ".selected") :idx el { removeClass: el "selected" } addClass: node "selected" } selectQuery <- :selector { selectQuery: selector in: (foreign: undefined) } selectQuery:in <- :selector :context { each: (qall: ".selected") :idx el { removeClass: el "selected" } each: (qall: selector context) :idx el { addClass: el "selected" } } selectParent <- :node { each: (qall: ".selectParent") :idx el { removeClass: el "selectParent" } addClass: node "selectParent" } popInscope:onClick <- :syms :handler { inscope <- q: "#inscope" inscope innerHTML!: "" each: syms :idx key { inscope appendChild: (newEl: "li" #{ textContent <- key onclick <- :Event { handler: key } }) } } scalarClick <- :domnode astnode event { selectNode: domnode setSelection: astnode event stopPropagation: (foreign: undefined) //TODO: set focus } symbolClick <- :domnode astnode event { selectNode: domnode popInscope: ((astnode symbols) allSymbols: (foreign: undefined)) onClick: :key { domnode textContent!: key astnode name!: key } setSelection: astnode event stopPropagation: (foreign: undefined) } assignClick <- :domnode astnode event { selectParent: domnode selectQuery: ".selectParent > .varname" in: domnode popInscope: ((astnode symbols) allSymbols: (foreign: undefined)) onClick: :key { (domnode firstChild) textContent!: key (astnode symbol) name!: key } setSelection: astnode withInNode: (astnode expression) event stopPropagation: (foreign: undefined) } opClick <- :domnode astnode event { selectParent: domnode selectQuery: ".selectParent > .opname" in: domnode showOps setSelection: astnode withInNode: (astnode left) event stopPropagation: (foreign: undefined) } funClick <- :domnode astnode event { selectParent: domnode selectQuery: ".selectParent > .funpart" in: domnode symtable <- astnode symbols syms <- filter: (symtable allSymbols: (foreign: undefined)) :sym { isLambda: ((symtable find: sym) def) } inner <- if: (astnode receiver) != (foreign: null) { astnode receiver } else: { (astnode args) getEl: 0 } setSelection: astnode withInNode: inner popInscope: syms onClick: :key { astnode name!: key parts <- key split: ":" nodes <- [] each: (domnode children) :idx val{ nodes push: val } partIdx <- 0 nodeIdx <- 0 lastWasNamePart <- true while: { partIdx < (parts length) || nodeIdx < (nodes length) } do: { if: nodeIdx < (nodes length) { node <-getEl: nodes nodeIdx nodeIdx <- nodeIdx + 1 if: (hasClass: node "funpart") { if: partIdx < (parts length) { postfix <- if: partIdx = 0 && nodeIdx = 2 && (parts length) = 1 && (nodes length) = 2 { "" } else: { ":" } t <- (getEl: parts partIdx) node textContent!: (getEl: parts partIdx) . postfix partIdx <- partIdx + 1 } else: { domnode removeChild: node } lastWasNamePart <- true } else: { if: (not: lastWasNamePart) && partIdx < (parts length) && nodeIdx > 0 { domnode insertBefore: (newEl: "span" #{ className <- "funpart selected" textContent <- (getEl: parts partIdx) . ":" }) node partIdx <- partIdx + 1 } lastWasNamePart <- false } } else: { console log: "part: " . (getEl: parts partIdx) domnode appendChild: (newEl: "span" #{ className <- "funpart selected" textContent <- (getEl: parts partIdx) . ":" }) partIdx <- partIdx + 1 } } } event stopPropagation: (foreign: undefined) } replaceNode:with <- :astnode domnode :newnode { } lambdaClick <- :domnode astnode event { selectNode: domnode popInscope: ((astnode symbols) allSymbols: (foreign: undefined)) onClick: :key { replaceNode: astnode domnode with: (create_symbol: key) } inner <- if: ((astnode args) length) > 0 { (astnode args) getEl: 0 } else: { (astnode expressions) getEl: 0 } setSelection: astnode withInNode: inner event stopPropagation: (foreign: undefined) } objectClick <- :domnode astnode event { selectNode: domnode popInscope: ((astnode symbols) allSymbols: (foreign: undefined)) onClick: :key { console log: "fooobar!" } setSelection: astnode withInNode: ((astnode messages) getEl: 0) event stopPropagation: (foreign: undefined) } visible <- "showops" showOps <- { each: (qall: ".controls") :idx el { removeClass: el visible addClass: el "showops" } visible <- "showops" } showLit <- { each: (qall: ".controls") :idx el { removeClass: el visible addClass: el "showlit" } visible <- "showlit" } main <- { get: "/src/" :data { fakeEl <- newEl: "div" #{ innerHTML <- data response } each: (qall: "a" fakeEl) :idx el { if: ((el textContent) = "../") {} else: { nel <- newEl: "a" #{ href <- "/edit/src/" + (el textContent) textContent <- el textContent } nel onclick!: :event { link <- foreign: this path <- link href path <- path substr: (path indexOf: "/edit/") + 5 editFile: path foreign: false } li <- newEl: "li" li appendChild: nel (q: "#browser ul") appendChild: li } } } //bind handlers for editor buttons each: (qall: ".controls li") :idx el { el onclick!: :event { srcel <- (q: "#src") srcel textContent!: (srcel textContent) + (el textContent) } } (q: "#ops_button") onclick!: :event { showOps } (q: "#lit_button") onclick!: :event { showLit } (q: "#in") onclick!: :event { console log: "inwards" if: (selection valid?) { selection in } } (q: "#out") onclick!: :event { console log: "outwards" if: (selection valid?) { selection out } } (q: "#next") onclick!: :event { if: (selection valid?) { selection next } } (q: "#prev") onclick!: :event { if: (selection valid?) { selection previous } } path <- (window location) pathname if: (path indexOf: "/edit/") = 0 { editFile: (path substr: 5) } (q: "#fullscreen") onclick!: :event { goFullScreen: } } }