Add support for compiler options
This commit is contained in:
parent
9b001050ef
commit
608cf5a1e8
|
@ -0,0 +1,11 @@
|
|||
ALTER TABLE wrappers DROP COLUMN is_asm;
|
||||
|
||||
UPDATE wrappers SET code = 'python3 code' WHERE code = 'python3 %s code';
|
||||
UPDATE wrappers SET code = 'sh code' WHERE code = 'sh %s code';
|
||||
UPDATE wrappers SET code = 'sqlite3 < code' WHERE code = 'sqlite3 %s < code';
|
||||
UPDATE wrappers SET code = 'mv code code.rs && rustc code.rs && ./code' WHERE code = 'mv code code.rs && rustc %s code.rs && ./code';
|
||||
UPDATE wrappers SET code = 'perl6 code' WHERE code = 'perl6 %s code';
|
||||
|
||||
DELETE FROM wrappers WHERE language_id = (SELECT language_id FROM languages WHERE name = 'Rust') AND label = 'ASM';
|
||||
|
||||
UPDATE wrappers SET ordering = 2 WHERE label = 'Rustfmt';
|
|
@ -0,0 +1,13 @@
|
|||
ALTER TABLE wrappers ADD COLUMN is_asm boolean NOT NULL DEFAULT FALSE;
|
||||
|
||||
UPDATE wrappers SET code = 'python3 %s code' WHERE code = 'python3 code';
|
||||
UPDATE wrappers SET code = 'sh %s code' WHERE code = 'sh code';
|
||||
UPDATE wrappers SET code = 'sqlite3 %s < code' WHERE code = 'sqlite3 < code';
|
||||
UPDATE wrappers SET code = 'mv code code.rs && rustc %s code.rs && ./code' WHERE code = 'mv code code.rs && rustc code.rs && ./code';
|
||||
UPDATE wrappers SET code = 'perl6 %s code' WHERE code = 'perl6 code';
|
||||
|
||||
UPDATE wrappers SET ordering = 3 WHERE label = 'Rustfmt';
|
||||
|
||||
INSERT INTO wrappers (language_id, label, code, ordering, is_asm)
|
||||
SELECT language_id, 'ASM', 'rustc --emit asm --crate-type rlib code && cat code.s', 2, TRUE
|
||||
FROM languages WHERE name = 'Rust';
|
|
@ -27,6 +27,7 @@ struct ApiLanguage {
|
|||
struct Wrapper {
|
||||
id: i32,
|
||||
label: String,
|
||||
is_asm: bool,
|
||||
is_formatter: bool,
|
||||
}
|
||||
|
||||
|
@ -49,6 +50,7 @@ pub fn api_language(
|
|||
.select((
|
||||
wrappers::wrapper_id,
|
||||
wrappers::label,
|
||||
wrappers::is_asm,
|
||||
wrappers::is_formatter,
|
||||
))
|
||||
.order(wrappers::ordering)
|
||||
|
|
|
@ -16,8 +16,10 @@ lazy_static! {
|
|||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Form {
|
||||
code: String,
|
||||
compiler_options: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -42,7 +44,10 @@ struct Output {
|
|||
|
||||
pub fn run(
|
||||
id: i32,
|
||||
Form { code }: Form,
|
||||
Form {
|
||||
code,
|
||||
compiler_options,
|
||||
}: Form,
|
||||
pool: &'static PgPool,
|
||||
) -> impl Future<Item = impl Reply, Error = Rejection> {
|
||||
wrappers::table
|
||||
|
@ -54,7 +59,7 @@ pub fn run(
|
|||
.map(|wrapper| wrapper.ok_or_else(warp::reject::not_found))
|
||||
.map_err(warp::reject::custom)
|
||||
.flatten()
|
||||
.and_then(|language_code| {
|
||||
.and_then(move |language_code: String| {
|
||||
CLIENT
|
||||
.post(SANDBOX_URL.as_str())
|
||||
.json(&Request {
|
||||
|
@ -63,7 +68,7 @@ pub fn run(
|
|||
contents: code,
|
||||
}],
|
||||
stdin: "",
|
||||
code: language_code,
|
||||
code: language_code.replace("%s", &compiler_options),
|
||||
})
|
||||
.send()
|
||||
.and_then(|mut r| r.json())
|
||||
|
|
|
@ -28,6 +28,7 @@ table! {
|
|||
code -> Text,
|
||||
ordering -> Int4,
|
||||
is_formatter -> Bool,
|
||||
is_asm -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,22 +27,35 @@ function fetchLanguage(id) {
|
|||
return future
|
||||
}
|
||||
|
||||
let abortEval = new AbortController
|
||||
const wrapperButtons = document.getElementById('wrapper-buttons')
|
||||
const compilerOptions = document.createElement('input')
|
||||
compilerOptions.placeholder = 'Compiler options'
|
||||
const buttons = document.createElement('span')
|
||||
wrapperButtons.append(compilerOptions, buttons)
|
||||
|
||||
const filterAsm = document.createElement('label')
|
||||
const filterAsmCheckbox = document.createElement('input')
|
||||
filterAsmCheckbox.type = 'checkbox'
|
||||
filterAsmCheckbox.checked = true
|
||||
filterAsm.append(' ', filterAsmCheckbox, ' Filter assembler directives')
|
||||
const filterRegex = /(?:\t\.(?:text|file|section|globl|p2align|type|cfi_.*|size|section)\b|.Lfunc_end).*\n?/g
|
||||
|
||||
let abortEval = new AbortController
|
||||
async function updateLanguage() {
|
||||
const initialValue = language.selectedOptions[0].value
|
||||
const { mime, mode, wrappers } = await fetchLanguage(initialValue)
|
||||
if (initialValue === language.selectedOptions[0].value) {
|
||||
editor.setOption('mode', mime)
|
||||
CodeMirror.autoLoadMode(editor, mode)
|
||||
const buttons = document.getElementById('wrapper-buttons')
|
||||
buttons.textContent = ''
|
||||
for (const { id, label, isFormatter } of wrappers) {
|
||||
compilerOptions.style.display = wrappers.length ? 'inline' : 'none'
|
||||
for (const { id, label, isAsm, isFormatter } of wrappers) {
|
||||
const button = document.createElement('button')
|
||||
button.textContent = label
|
||||
button.addEventListener('click', e => {
|
||||
e.preventDefault()
|
||||
const body = new URLSearchParams
|
||||
body.append('compilerOptions', compilerOptions.value)
|
||||
body.append('code', editor.getValue())
|
||||
abortEval.abort()
|
||||
abortEval = new AbortController
|
||||
|
@ -58,7 +71,25 @@ async function updateLanguage() {
|
|||
output.textContent = ''
|
||||
fetch(`/api/v0/run/${id}`, parameters)
|
||||
.then(x => x.json())
|
||||
.catch(e => {
|
||||
if (e.name != 'AbortError')
|
||||
output.textContent = 'An error occured while running the code. Try again.'
|
||||
})
|
||||
.then(({ status, stdout, stderr }) => {
|
||||
function updateStdout() {
|
||||
if (stdout) {
|
||||
if (isAsm && filterAsmCheckbox.checked) {
|
||||
stdoutElement.textContent = stdout.replace(filterRegex, "")
|
||||
} else {
|
||||
stdoutElement.textContent = stdout
|
||||
}
|
||||
} else {
|
||||
const italic = document.createElement('i')
|
||||
italic.textContent = '(no output)'
|
||||
stdoutElement.append(italic)
|
||||
}
|
||||
}
|
||||
let stdoutElement
|
||||
if (stderr) {
|
||||
const stderrHeader = document.createElement('h2')
|
||||
stderrHeader.textContent = 'Standard error'
|
||||
|
@ -69,26 +100,23 @@ async function updateLanguage() {
|
|||
if (isFormatter) {
|
||||
editor.setValue(stdout)
|
||||
} else {
|
||||
const stdoutHeader = document.createElement('h2')
|
||||
stdoutHeader.textContent = 'Standard output'
|
||||
const stdoutHeader = document.createElement('div')
|
||||
stdoutHeader.className = 'stdout-header'
|
||||
const stdoutHeaderH2 = document.createElement('h2')
|
||||
stdoutHeaderH2.textContent = 'Standard output'
|
||||
if (status) {
|
||||
stdoutHeader.textContent += ` (exit code ${status})`
|
||||
stdoutHeaderH2.textContent += ` (exit code ${status})`
|
||||
}
|
||||
const stdoutElement = document.createElement('pre')
|
||||
if (stdout) {
|
||||
stdoutElement.textContent = stdout
|
||||
} else {
|
||||
const italic = document.createElement('i')
|
||||
italic.textContent = '(no output)'
|
||||
stdoutElement.append(italic)
|
||||
stdoutHeader.append(stdoutHeaderH2)
|
||||
if (isAsm) {
|
||||
stdoutHeader.append(filterAsm)
|
||||
filterAsmCheckbox.onchange = updateStdout
|
||||
}
|
||||
stdoutElement = document.createElement('pre')
|
||||
updateStdout()
|
||||
output.append(stdoutHeader, stdoutElement)
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
if (e.name != 'AbortError')
|
||||
output.textContent = 'An error occured while running the code. Try again.'
|
||||
})
|
||||
})
|
||||
buttons.appendChild(button)
|
||||
}
|
||||
|
|
|
@ -79,3 +79,9 @@ pre, code {
|
|||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
.stdout-header h2, .stdout-header label {
|
||||
display: inline-block;
|
||||
}
|
||||
.stdout-header label {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user