Skip to content

Commit

Permalink
Add support for CFSM demo in webservice
Browse files Browse the repository at this point in the history
  • Loading branch information
nickng committed Jan 6, 2017
1 parent 936a9c9 commit bd13fac
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 3 deletions.
27 changes: 27 additions & 0 deletions static/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,33 @@ $('#gong').on('click', function() {
$('#gong-output-close').on('click', function() {
$('#gong-wrap').removeClass('visible');
})
$('#synthesis').on('click', function() {
if ($('#out').attr('lang') != 'CFSM') {
return false
}
reportTime('');
$.ajax({
url: '/synthesis?chan='+$('#chan-cfsm').val(),
type: 'POST',
data: migoCode(),
async: true,
success: function(msg) {
var obj = JSON.parse(msg);
if (obj!=null&&obj.SMC!=null) {
writeTo(obj.SMC, '#synthesis-output');
$('#synthesis-global').html(obj.Global)
$('#synthesis-machines').html(obj.Machines)
reportTime(obj.time);
$('#synthesis-wrap').addClass('visible');
} else {
writeTo("JSON error", '#synthesis-output');
}
}
});
});
$('#synthesis-output-close').on('click', function() {
$('#synthesis-wrap').removeClass('visible');
})
writeTo('// Write Go code here\n'
+ 'package main\n\n'
+ 'import "fmt"\n\n'
Expand Down
19 changes: 18 additions & 1 deletion static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ div.output {
bottom: 0;
position: absolute;
}
div#synthesis-wrap,
div#gong-wrap {
position: absolute;
display: none;
right: 10px;
bottom: 10px;
}
div#synthesis-wrap.visible,
div#gong-wrap.visible {
opacity: 0.95;
position: absolute;
Expand Down Expand Up @@ -87,7 +89,8 @@ div#out:not([lang]) + div.buttons,
div#out[lang] + div.buttons {
display: none;
}
div#out[lang='migo'] + div.buttons {
div#out[lang='MiGo'] + div.buttons,
div#out[lang='CFSM'] + div.buttons {
display: block;
}
#time {
Expand Down Expand Up @@ -169,3 +172,17 @@ div.controls button:hover {
background: #28849b;
text-decoration: none;
}

div#synthesis-graphics {
max-width: 1000px;
overflow-x: auto;
background: #ccc;
}

div#synthesis-graphics div#synthesis-machines,
div#synthesis-graphics div#synthesis-global {
display: table-cell;
padding: 5px;
vertical-align: middle;
}

11 changes: 9 additions & 2 deletions templates/index.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</div>
<div class='controls'>
<button name='cfsm' id='cfsm'>Show CFSM</button>
<button name='migo' id='migo'>Show MiGo (to run Gong)</button>
<button name='migo' id='migo'>Show MiGo</button>
<button name='ssa' id='ssa'>Show SSA</button>
{{- if .Examples -}}
<select name='example' id='examples' class='left'>
Expand All @@ -29,8 +29,15 @@
</div>
<div class='generated'>
<div class='code' id='out' spellcheck='false' contenteditable='false'>No output.</div>
<div class='buttons'><button name='gong' id='gong'>Run Gong</button></div>
<div class='buttons'>
<button name='gong' id='gong'>Run Gong</button>
<button name='synthesis' id='synthesis'>Run Synthesis</button> <input name='chan-cfsm' id='chan-cfsm' value='1' placeholder='Chan CFSMs'/>
</div>
<div id='gong-wrap'><div id='gong-output'></div><div class='buttons'><button id='gong-output-close'>Close</button></div></div>
<div id='synthesis-wrap'><div id='synthesis-output'></div>
<div id='synthesis-graphics'><div id='synthesis-machines'></div><div id='synthesis-global'></div></div>
<div class='buttons'><button id='synthesis-output-close'>Close</button></div>
</div>
</div>
<script src='/play.js'></script>
<script src='/static/script.js'></script>
Expand Down
1 change: 1 addition & 0 deletions webservice/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (s *Server) Start() {
http.HandleFunc("/cfsm", cfsmHandler)
http.HandleFunc("/migo", migoHandler)
http.HandleFunc("/gong", gongHandler)
http.HandleFunc("/synthesis", synthesisHandler)

log.Printf("Listening at %s", s.URL())
(&http.Server{}).Serve(s.Listener())
Expand Down
119 changes: 119 additions & 0 deletions webservice/synthesis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package webservice

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path"
"strings"
"time"
)

func synthesisHandler(w http.ResponseWriter, req *http.Request) {
log.Println("Running SMC check on snippet")
b, err := ioutil.ReadAll(req.Body)
if err != nil {
NewErrInternal(err, "Cannot read input CFSM").Report(w)
}
req.Body.Close()
chanCFSMs := req.FormValue("chan")

// ---- Executables ----
log.Println("Finding required executables")
gmc, err := exec.LookPath("GMC")
if err != nil {
NewErrInternal(err, "Cannot find GMC executable (Check $PATH?)").Report(w)
}
bg, err := exec.LookPath("BuildGlobal")
if err != nil {
NewErrInternal(err, "Cannot find BuildGobal executable (Check $PATH?)").Report(w)
}
petrify, err := exec.LookPath("petrify")
if err != nil {
NewErrInternal(err, "Cannot find petrify executable (Check $PATH?)").Report(w)
}
dot, err := exec.LookPath("dot")
if err != nil {
NewErrInternal(err, "Cannot find dot executable (Check $PATH?)").Report(w)
}

// ---- Output dirs/files ----
baseDir := path.Join(os.TempDir(), "syn")
err = os.MkdirAll(baseDir, 0777)
if err != nil {
NewErrInternal(err, "Cannot create temp dir").Report(w)
}
err = os.MkdirAll(path.Join(baseDir, "outputs"), 0777)
if err != nil {
NewErrInternal(err, "Cannot create final output dir").Report(w)
}
err = os.Chdir(baseDir)
if err != nil {
NewErrInternal(err, "Cannot chdir to temp dir").Report(w)
}
file, err := ioutil.TempFile(baseDir, "cfsm")
if err != nil {
NewErrInternal(err, "Cannot create temp file for CFSM input").Report(w)
}
defer os.Remove(file.Name())
toPetrifyPath := path.Join(baseDir, "outputs", fmt.Sprintf("%s_toPetrify", path.Base(file.Name())))
petriPath := path.Join(baseDir, "default")
machinesDotPath := path.Join(baseDir, "outputs", fmt.Sprintf("%s_machines.dot", path.Base(file.Name())))
globalDotPath := path.Join(baseDir, "outputs", "default_global.dot")

if _, err := file.Write(b); err != nil {
NewErrInternal(err, "Cannot write to temp file for CFSM input").Report(w)
}
if err := file.Close(); err != nil {
NewErrInternal(err, "Cannot close temp file for CFSM input").Report(w)
}

// Replace symbols
re := strings.NewReplacer("AAA", "->", "CCC", ",", "COCO", ":")
outReplacer := strings.NewReplacer("True", "<span style='color: #87ff87; font-weight: bold'>True</span>", "False", "<span style='color: #ff005f; font-weight: bold'>False</span>")

startTime := time.Now()
gmcOut, err := exec.Command(gmc, file.Name(), chanCFSMs, "+RTS", "-N").CombinedOutput()
if err != nil {
log.Printf("GMC execution failed: %v\n", err)
}
petriOut, err := exec.Command(petrify, "-dead", "-ip", toPetrifyPath).CombinedOutput()
if err != nil {
log.Printf("petrify execution failed: %v\n", err)
}
ioutil.WriteFile(petriPath, []byte(re.Replace(string(petriOut))), 0664)
bgOut, err := exec.Command(bg, petriPath).CombinedOutput()
if err != nil {
log.Printf("BuildGlobal execution failed: %v\n", err)
}
log.Println("BuildGlobal:", string(bgOut))

execTime := time.Now().Sub(startTime)

machinesSVG, err := exec.Command(dot, "-Tsvg", machinesDotPath).CombinedOutput()
if err != nil {
log.Printf("dot execution failed for : %v\n", err)
}
globalSVG, err := exec.Command(dot, "-Tsvg", globalDotPath).CombinedOutput()
if err != nil {
log.Printf("dot execution failed for : %v\n", err)
}

reply := struct {
SMC string `json:"SMC"`
Machines string `json:"Machines"`
Global string `json:"Global"`
Time string `json:"time"`
}{
SMC: outReplacer.Replace(string(gmcOut)),
Machines: string(machinesSVG),
Global: string(globalSVG),
Time: execTime.String(),
}
log.Println("Synthesis completed in", execTime.String())
json.NewEncoder(w).Encode(&reply)
}

0 comments on commit bd13fac

Please sign in to comment.