-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
395 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: _build/default/web/apigen.exe -p $PORT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/bin/bash | ||
|
||
set -eu | ||
|
||
BUILD_DIR="$1" | ||
CACHE_DIR="$2" | ||
ENV_DIR="$1" | ||
|
||
export PATH="/tmp/opam:$PATH" | ||
export OPAMROOT="$CACHE_DIR/opam" | ||
|
||
# Download opam. | ||
echo "/tmp/opam | ||
Y" | sh <(curl -sL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) | ||
|
||
# Enter source directory. | ||
cd "$BUILD_DIR" | ||
|
||
. "$BUILD_DIR/bin/install-deps" | ||
|
||
# Build our app. | ||
dune build --profile release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
|
||
set -eux | ||
|
||
# Set up opam, install dune and menhir (it's not a library dependency). | ||
opam init --disable-sandboxing -n | ||
opam install dune menhir -y | ||
|
||
eval $(opam env) | ||
|
||
# Install dependencies: we keep installing dependencies until dune stops telling | ||
# us to install more. | ||
DUNE_CMD='dune external-lib-deps --missing --profile release @@default |& grep -o "opam install .*" || true' | ||
INSTALL_CMD="$(eval $DUNE_CMD)" | ||
while [ -n "$INSTALL_CMD" ]; do | ||
$INSTALL_CMD -y | ||
INSTALL_CMD="$(eval $DUNE_CMD)" | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
function processResult(result, error, output) { | ||
if (result[0] === 1) { | ||
error.innerText = result[1]; | ||
output.innerText = ""; | ||
} else { | ||
error.innerText = ""; | ||
output.innerText = result[1]; | ||
} | ||
} | ||
|
||
function processLocal(input, format, output, error) { | ||
let result = apidsl.parse("input.api.h", input); | ||
if (result[0] === 0) { | ||
if (format === "haskell") { | ||
result = apidsl.haskell("MyAPI", result[1]); | ||
} else { | ||
result = apidsl[format](result[1]); | ||
} | ||
} | ||
|
||
processResult(result, error, output); | ||
} | ||
|
||
function processRemote(input, format, output, error) { | ||
const apiUrl = "https://apidsl2.herokuapp.com"; | ||
fetch(apiUrl + "/parse", { | ||
method: "POST", | ||
body: JSON.stringify(["Request", input]) | ||
}).then((data) => data.json()).then((result) => { | ||
if (result[0] === 0) { | ||
fetch(apiUrl + "/" + format, { | ||
method: "POST", | ||
body: JSON.stringify(["Request", result[1]]) | ||
}).then((data) => data.json()).then((result) => { | ||
processResult(result, error, output); | ||
}); | ||
} else { | ||
processResult(result, error, output); | ||
} | ||
}); | ||
} | ||
|
||
function exceptionType(err) { | ||
if (err instanceof Array) { | ||
if (err[1] instanceof Object && "c" in err[1]) { | ||
return err[1].c; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
function isStackOverflow(err) { | ||
return exceptionType(err) === "Stack_overflow" || | ||
(exceptionType(err) === "Js_of_ocaml__Js.Error" && | ||
err[2].includes("Maximum call stack size exceeded")); | ||
} | ||
|
||
function process() { | ||
let error = document.getElementById("error"); | ||
let input = document.getElementById("input").value; | ||
let output = document.getElementById("output"); | ||
let format = document.querySelector("input[name="format"]:checked").value; | ||
|
||
try { | ||
processLocal(input, format, output, error); | ||
} catch (err) { | ||
if (isStackOverflow(err)) { | ||
processRemote(input, format, output, error); | ||
} else { | ||
console.log("Unhandled exception ", err); | ||
} | ||
} | ||
} | ||
|
||
function load(snippet) { | ||
const snippets = { | ||
"simple": "static int main();", | ||
"comment": | ||
`/** | ||
* The main function. | ||
*/ | ||
static int main();`, | ||
"namespace": | ||
`namespace foo { | ||
/** | ||
* This is $main. | ||
*/ | ||
static int32_t main(); | ||
}`, | ||
"large": | ||
`class foo { | ||
/** | ||
* The "this" type for all non-static functions. | ||
*/ | ||
struct this; | ||
/** | ||
* This is $main. | ||
*/ | ||
int32_t main(); | ||
namespace bar { | ||
uint32_t blep(); | ||
} | ||
uint8_t some_property { get(); set(); } | ||
}` | ||
}; | ||
|
||
const fileUrl = "https://raw.githubusercontent.com/TokTok/c-toxcore/master/toxcore/tox.api.h"; | ||
|
||
let input = document.getElementById("input"); | ||
if (snippet === "tox") { | ||
fetch(fileUrl).then(data => data.text()).then(text => { | ||
input.value = text; | ||
process(); | ||
}); | ||
} else { | ||
input.value = snippets[snippet]; | ||
process(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
open Apidsl | ||
open Js_of_ocaml | ||
|
||
let () = | ||
Js.Unsafe.global##.apidsl := (object%js | ||
val parse = Js.wrap_callback (fun file contents -> | ||
try | ||
Ok (ApiPasses.parse_string | ||
(Js.to_string file) | ||
(Js.to_string contents)) | ||
with | ||
| Failure(x) -> Error(Js.string x) | ||
| ApiLexer.Lexing_error(start_p, token) -> | ||
let error = ApiPasses.format_lex_error start_p token in | ||
Error(Js.string error)) | ||
|
||
val ast = Js.wrap_callback (fun api -> | ||
try Ok (Js.string (ApiAst.show_api Format.pp_print_string api)) | ||
with Failure(x) -> Error(Js.string x)) | ||
|
||
val api = Js.wrap_callback (fun api -> | ||
let ApiAst.Api (pre, ast, post) = api in | ||
try Ok (Js.string (ApiPasses.dump_api pre ast post)) | ||
with Failure(x) -> Error(Js.string x)) | ||
|
||
val c = Js.wrap_callback (fun api -> | ||
let ApiAst.Api (pre, ast, post) = api in | ||
try Ok (Js.string (ApiPasses.all pre ast post)) | ||
with Failure(x) -> Error(Js.string x)) | ||
|
||
val haskell = Js.wrap_callback (fun modname api -> | ||
let ApiAst.Api (_, ast, _) = api in | ||
try Ok (Js.string (ApiPasses.haskell (Js.to_string modname) ast)) | ||
with Failure(x) -> Error(Js.string x)) | ||
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
(executable | ||
(name apigen) | ||
(libraries apidsl) | ||
(preprocess (pps js_of_ocaml-ppx)) | ||
(modes js)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>ApiDSL header generator</title> | ||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | ||
<script type="text/javascript" src="apigen.bc.js"></script> | ||
<script type="text/javascript" src="apidsl-support.js"></script> | ||
<style> | ||
#editor { width: 100%; height: 100%; } | ||
#error { color: red; } | ||
#left { background-color: #eee; width: 50%; } | ||
#right { background-color: #aea; width: 50%; } | ||
#input { width: 100%; height: 100%; box-sizing: border-box; } | ||
#output { width: 100%; height: 100%; } | ||
body { vertical-align: top; } | ||
</style> | ||
</head> | ||
<body> | ||
<h2>ApiDSL editor</h2> | ||
<form onchange="process()"> | ||
Output format: | ||
<input type="radio" id="api" name="format" value="api" checked="checked"> | ||
<label for="api">ApiDSL</label> | ||
<input type="radio" id="c" name="format" value="c"> | ||
<label for="c">C</label> | ||
<input type="radio" id="haskell" name="format" value="haskell"> | ||
<label for="haskell">Haskell</label> | ||
<input type="radio" id="ast" name="format" value="ast"> | ||
<label for="ast">AST</label> | ||
</form> | ||
<table id="editor"> | ||
<tr style="height: 20em;"> | ||
<td id="left"> | ||
<textarea id="input" oninput="process()"></textarea> | ||
</td> | ||
<td id="right"> | ||
<pre id="output"></pre> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td id="error"></td> | ||
</tr> | ||
</table> | ||
<h2>Examples</h2> | ||
<ul id="examples"> | ||
<li><a href="#" onclick="load('simple')">Simple declaration</a></li> | ||
<li><a href="#" onclick="load('comment')">Declaration with comment</a></li> | ||
<li><a href="#" onclick="load('namespace')">Namespaced functions and comment references</a></li> | ||
<li><a href="#" onclick="load('large')">Larger complex example</a></li> | ||
<li><a href="#" onclick="load('tox')">tox.api.h</a></li> | ||
</ul> | ||
</body> | ||
</html> |
Oops, something went wrong.