From 84c94a17fee835235c4f741dc6cdc3d5fe1fd935 Mon Sep 17 00:00:00 2001 From: ellonamac Date: Thu, 18 Jul 2024 15:01:33 -0400 Subject: [PATCH 01/33] praxly team section added --- index.html | 19 ++++++++++++++++++- public/index.css | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 2ee6b69..9af2913 100644 --- a/index.html +++ b/index.html @@ -40,21 +40,38 @@

Welcome to Praxly 🍂

src="/embed.html?button=both&result=both#code=%2F%2F%0A%2F%2F%20Sample%20Question%208%0A%2F%2F%0A%0Avoid%20swap(int%5B%5D%20arr%2C%20int%20i%2C%20int%20j)%0A%20%20%20%20int%20temp%20←%20arr%5Bi%5D%0A%20%20%20%20arr%5Bi%5D%20←%20arr%5Bj%5D%0A%20%20%20%20arr%5Bj%5D%20←%20temp%0Aend%20swap%0A%0Avoid%20sort(int%5B%5D%20arr%2C%20int%20len)%0A%20%20%20%20int%20pos%20←%200%0A%20%20%20%20while%20(pos%20<%20len)%0A%20%20%20%20%20%20%20%20if%20(pos%20%3D%3D%200)%0A%20%20%20%20%20%20%20%20%20%20%20%20pos%20←%20pos%20%2B%201%0A%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(arr%5Bpos%5D%20>%20arr%5Bpos%20-%201%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pos%20←%20pos%20%2B%201%0A%20%20%20%20%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20swap(arr%2C%20pos%2C%20pos%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pos%20←%20pos%20-%201%0A%20%20%20%20%20%20%20%20%20%20%20%20end%20if%0A%20%20%20%20%20%20%20%20end%20if%0A%20%20%20%20end%20while%0Aend%20sort%0A%0Aint%5B%5D%20numbers%20←%20%7B2%2C%201%2C%205%2C%203%2C%204%7D%0Asort(numbers%2C%205)%0Aprint%20numbers%0A"> +
+
+
+ +

Praxly Team

+
- + + Team member 1 +

Ben Saupp

+
+ Team member 2 +

Ellona Macmillan

+ Team member 3 +

Michael Stewart

+ Team member 3 +

Chris Mayfield

+ Team member 3 +

Chirs Johnson

diff --git a/public/index.css b/public/index.css index 7dd7161..5db7185 100644 --- a/public/index.css +++ b/public/index.css @@ -85,3 +85,24 @@ body { position: absolute; transform: rotate(-45deg); } + +.people-container { + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.team-member img { + flex: 0 1 30%; + max-width: 100%; + border-radius: 50%; + height: 200px; + width: 200px; + padding: 15px; + object-fit: cover; +} + +.team-member h3 { + margin: 0 0 15px; + +} From c8f04207c1f14397dc691381ed8a95bfdea7a46a Mon Sep 17 00:00:00 2001 From: ellonamac Date: Thu, 18 Jul 2024 15:04:03 -0400 Subject: [PATCH 02/33] rotating bugs --- public/index.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/public/index.css b/public/index.css index 5db7185..6fa1afa 100644 --- a/public/index.css +++ b/public/index.css @@ -84,6 +84,11 @@ body { font-size: 29px; position: absolute; transform: rotate(-45deg); + transition: transform 1s ease-in-out; +} + +.material-symbols-rounded.bug:hover { + transform: rotate(315deg); } .people-container { @@ -104,5 +109,4 @@ body { .team-member h3 { margin: 0 0 15px; - } From 9e7675161f88e57ce76972eb9a42b031282d51bf Mon Sep 17 00:00:00 2001 From: ellonamac Date: Fri, 19 Jul 2024 12:02:33 -0400 Subject: [PATCH 03/33] basic layout for praxly team finished --- index.html | 64 ++++++++++++++++++++++++++++++++++-------------- public/index.css | 24 ++++++++++++++++++ 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/index.html b/index.html index 9af2913..bc9de45 100644 --- a/index.html +++ b/index.html @@ -8,13 +8,15 @@ + href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
- Report a bug pest_control + Report + a bug pest_control
@@ -48,32 +50,51 @@

Praxly Team

- - Team member 1 + + Team member 1

Ben Saupp

- +
+

I created Praxly during junior and senior year at JMU. + I have been a Lead TA for the computer science department, graduating in May 2024 with a Bachelors Degree in + CS + with a minor in Mathematics.

+
- - Team member 2 -

Ellona Macmillan

+ + Team member 2 +

Ellona Macmillan

+
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity + as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and + yellows fluttering to the ground
- - Team member 3 -

Michael Stewart

-
+ + Team member 4 +

Chris Mayfield

+
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity + as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and + yellows fluttering to the ground
+
- - Team member 3 -

Chris Mayfield

+ + Team member 5 +

Chris Johnson

+
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity + as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and + yellows fluttering to the ground
- - Team member 3 -

Chirs Johnson

+ + Team member 3 +

Michael Stewart

+
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity + as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and + yellows fluttering to the ground
+ +
diff --git a/public/index.css b/public/index.css index 2a507f7..77b6947 100644 --- a/public/index.css +++ b/public/index.css @@ -88,7 +88,8 @@ body { transition: transform 1s ease-in-out; } -.material-symbols-rounded.bug:hover { +.report:hover .bug, +.report .bug:hover { transform: rotate(315deg); } @@ -99,7 +100,7 @@ body { max-width: 900px; } -.team-member img { +.team-member .member { flex: 0 1 30%; max-width: 100%; border-radius: 50%; From 76a2a5f5de9e8aa2699f7ef6bc6b20109bd1d682 Mon Sep 17 00:00:00 2001 From: ellonamac Date: Fri, 19 Jul 2024 12:24:26 -0400 Subject: [PATCH 05/33] changed the report from a link to a button --- index.html | 9 ++++++--- public/index.css | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 7b3b12a..f069b6c 100644 --- a/index.html +++ b/index.html @@ -14,9 +14,7 @@
- Report - a bug pest_control +
@@ -108,6 +106,11 @@

Michael Stewart

const githubButton = document.querySelector('.github-button'); const peopleContainer = document.querySelector('.people-container'); const learnMoreButton = document.querySelector('.learn-more'); + const reportButton = document.querySelector('.report'); + + reportButton.addEventListener('click', function () { + window.open("https://docs.google.com/forms/d/e/1FAIpQLSeo2mUrrhNZejPch9UcQQDHWk5e6ql_xFfFSdS6oiaNA-Tk8Q/viewform?embedded=true", '_blank'); + }) praxlyButton.addEventListener('click', function () { window.open("/main.html", "_blank"); diff --git a/public/index.css b/public/index.css index 77b6947..16077fc 100644 --- a/public/index.css +++ b/public/index.css @@ -75,6 +75,8 @@ body { margin: 45px; margin-right: 60px; text-decoration: none; + background: transparent; + border: none; } .report:hover { From 3a52aa2baa05f2632014edb35a1e32824861f6f0 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Tue, 23 Jul 2024 07:23:39 -0400 Subject: [PATCH 06/33] Add type checking to random* and arity checking --- src/ast.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/ast.js b/src/ast.js index 8fb9be7..b22ba52 100644 --- a/src/ast.js +++ b/src/ast.js @@ -49,6 +49,12 @@ class ReturnException extends Error { } } +function checkArity(functionName, expectedArity, node) { + if (node.parameters.length !== expectedArity) { + throw new PraxlyError(`Function ${functionName} expects ${expectedArity} parameter${expectedArity === 1 ? '' : 's'}, not ${node.parameters.length}.`, node.line); + } +} + /** * This function will take the Intermediate Representation of the AST and creates an executable version of the tree. * This also gives it a chance to run static analysis. @@ -133,16 +139,22 @@ export function createExecutable(tree) { case NODETYPES.BUILTIN_FUNCTION_CALL: { if (tree.name === 'input') { + checkArity('input', 0, tree); return new Praxly_input(tree); } else if (tree.name === 'random') { + checkArity('random', 0, tree); return new Praxly_random(tree); } else if (tree.name === 'randomInt') { + checkArity('randomInt', 1, tree); return new Praxly_random_int(createExecutable(tree.parameters[0]), tree); } else if (tree.name === 'randomSeed') { + checkArity('randomSeed', 1, tree); return new Praxly_random_seed(createExecutable(tree.parameters[0]), tree); } else if (tree.name === 'int') { + checkArity('int', 1, tree); return new Praxly_int_conversion(createExecutable(tree.parameters[0]), tree); } else if (tree.name === 'float') { + checkArity('float', 1, tree); return new Praxly_float_conversion(createExecutable(tree.parameters[0]), tree); } else { throw new Error('unknown builtin function'); @@ -581,9 +593,14 @@ class Praxly_random_int { } async evaluate(environment) { - const maxValue = (await this.max.evaluate(environment)).value; - const x = prand.unsafeUniformIntDistribution(0, maxValue - 1, environment.global.random.generator); - return new Praxly_int(x, this.json); + const maxNode = (await this.max.evaluate(environment)); + if (maxNode.realType === 'int') { + const maxValue = maxNode.value; + const x = prand.unsafeUniformIntDistribution(0, maxValue - 1, environment.global.random.generator); + return new Praxly_int(x, this.json); + } else { + throw new PraxlyError(`randomInt's maximum parameter must be of type int, not ${maxNode.realType}.`, this.json.line); + } } } @@ -594,10 +611,15 @@ class Praxly_random_seed { } async evaluate(environment) { - const seedValue = (await this.seed.evaluate(environment)).value; - environment.global.random.seed = seedValue; - environment.global.random.generator = prand.xoroshiro128plus(seedValue); - return null; + const seedNode = (await this.seed.evaluate(environment)); + if (seedNode.realType === 'int') { + const seedValue = seedNode.value; + environment.global.random.seed = seedValue; + environment.global.random.generator = prand.xoroshiro128plus(seedValue); + return null; + } else { + throw new PraxlyError(`randomSeed's seed parameter must be of type int, not ${seedNode.realType}.`, this.json.line); + } } } From 8fba62cdad9602debb52c3d73864947850cbcda0 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Tue, 23 Jul 2024 07:28:24 -0400 Subject: [PATCH 07/33] Remove superfluous parameter to checkArity --- src/ast.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ast.js b/src/ast.js index b22ba52..624fa8f 100644 --- a/src/ast.js +++ b/src/ast.js @@ -49,9 +49,9 @@ class ReturnException extends Error { } } -function checkArity(functionName, expectedArity, node) { +function checkArity(node, expectedArity) { if (node.parameters.length !== expectedArity) { - throw new PraxlyError(`Function ${functionName} expects ${expectedArity} parameter${expectedArity === 1 ? '' : 's'}, not ${node.parameters.length}.`, node.line); + throw new PraxlyError(`Function ${node.name} expects ${expectedArity} parameter${expectedArity === 1 ? '' : 's'}, not ${node.parameters.length}.`, node.line); } } @@ -139,22 +139,22 @@ export function createExecutable(tree) { case NODETYPES.BUILTIN_FUNCTION_CALL: { if (tree.name === 'input') { - checkArity('input', 0, tree); + checkArity(tree, 0); return new Praxly_input(tree); } else if (tree.name === 'random') { - checkArity('random', 0, tree); + checkArity(tree, 0); return new Praxly_random(tree); } else if (tree.name === 'randomInt') { - checkArity('randomInt', 1, tree); + checkArity(tree, 1); return new Praxly_random_int(createExecutable(tree.parameters[0]), tree); } else if (tree.name === 'randomSeed') { - checkArity('randomSeed', 1, tree); + checkArity(tree, 1); return new Praxly_random_seed(createExecutable(tree.parameters[0]), tree); } else if (tree.name === 'int') { - checkArity('int', 1, tree); + checkArity(tree, 1); return new Praxly_int_conversion(createExecutable(tree.parameters[0]), tree); } else if (tree.name === 'float') { - checkArity('float', 1, tree); + checkArity(tree, 1); return new Praxly_float_conversion(createExecutable(tree.parameters[0]), tree); } else { throw new Error('unknown builtin function'); From 2fc56bcc8cd901c01a5e700def04e68d619b22b6 Mon Sep 17 00:00:00 2001 From: Chris Mayfield Date: Tue, 23 Jul 2024 09:28:59 -0400 Subject: [PATCH 08/33] added faculty photos; removed team member descriptions --- index.html | 47 +++++++++-------------------- public/images/picture_of_Ben.png | Bin 286584 -> 0 bytes public/index.css | 4 +++ public/people/johnson.png | Bin 0 -> 91389 bytes public/people/mayfield.jpg | Bin 0 -> 81924 bytes public/people/saupp.png | Bin 0 -> 227466 bytes public/people/stewart.jpg | Bin 0 -> 174315 bytes public/{images => people}/user.png | Bin 8 files changed, 19 insertions(+), 32 deletions(-) delete mode 100644 public/images/picture_of_Ben.png create mode 100644 public/people/johnson.png create mode 100644 public/people/mayfield.jpg create mode 100644 public/people/saupp.png create mode 100644 public/people/stewart.jpg rename public/{images => people}/user.png (100%) diff --git a/index.html b/index.html index f069b6c..95a5962 100644 --- a/index.html +++ b/index.html @@ -40,54 +40,37 @@

Welcome to Praxly 🍂

src="/embed.html?button=both&result=both#code=%2F%2F%0A%2F%2F%20Sample%20Question%208%0A%2F%2F%0A%0Avoid%20swap(int%5B%5D%20arr%2C%20int%20i%2C%20int%20j)%0A%20%20%20%20int%20temp%20←%20arr%5Bi%5D%0A%20%20%20%20arr%5Bi%5D%20←%20arr%5Bj%5D%0A%20%20%20%20arr%5Bj%5D%20←%20temp%0Aend%20swap%0A%0Avoid%20sort(int%5B%5D%20arr%2C%20int%20len)%0A%20%20%20%20int%20pos%20←%200%0A%20%20%20%20while%20(pos%20<%20len)%0A%20%20%20%20%20%20%20%20if%20(pos%20%3D%3D%200)%0A%20%20%20%20%20%20%20%20%20%20%20%20pos%20←%20pos%20%2B%201%0A%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(arr%5Bpos%5D%20>%20arr%5Bpos%20-%201%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pos%20←%20pos%20%2B%201%0A%20%20%20%20%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20swap(arr%2C%20pos%2C%20pos%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pos%20←%20pos%20-%201%0A%20%20%20%20%20%20%20%20%20%20%20%20end%20if%0A%20%20%20%20%20%20%20%20end%20if%0A%20%20%20%20end%20while%0Aend%20sort%0A%0Aint%5B%5D%20numbers%20←%20%7B2%2C%201%2C%205%2C%203%2C%204%7D%0Asort(numbers%2C%205)%0Aprint%20numbers%0A"> -

Praxly Team

- - Team member 1 +

Ben Saupp

-
-

I created Praxly during junior and senior year at JMU. - I have been a Lead TA for the computer science department, graduating in May 2024 with a Bachelors Degree in - CS - with a minor in Mathematics.

-
+
- - Team member 2 +

Ellona Macmillan

-
I am the current student continuing Ben's Research project with Praxly. I will be a Junior Computer Science student in the fall.
+
- - Team member 4 -

Chris Mayfield

-
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity - as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and - yellows fluttering to the ground
+ +

Dr. Chris Mayfield

+
- - Team member 5 -

Chris Johnson

-
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity - as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and - yellows fluttering to the ground
+ +

Dr. Chris Johnson

+
- - Team member 3 -

Michael Stewart

-
The cat jumped gracefully onto the windowsill, its tail twitching with curiosity - as it surveyed the world outside. A gentle breeze rustled the autumn leaves, sending a cascade of reds and - yellows fluttering to the ground
+ +

Dr. Michael Stewart

+
- +
-
delete

diff --git a/public/themes.css b/public/themes.css index 25419e0..dede0e5 100644 --- a/public/themes.css +++ b/public/themes.css @@ -546,16 +546,6 @@ body:not(.embed) #bottom-part { color: var(--output-text-color); } -.clearOut { - display: none; - position: absolute; - font-size: x-large; - top: 5px; - right: 10px; - cursor: pointer; -} - - .stdout { margin-top: 0; } diff --git a/src/common.js b/src/common.js index 6f35baa..2cb07be 100644 --- a/src/common.js +++ b/src/common.js @@ -101,9 +101,6 @@ export class PraxlyError extends Error { export const MAX_LOOP = 100; // prevents accidental infinite loops export var errorOutput = ""; -export var blockErrorsBuffer = {}; -export var annotationsBuffer = []; -export var markersBuffer = []; export function addToPrintBuffer(message) { const stdOut = document.querySelector('.stdout'); @@ -160,24 +157,6 @@ export function consoleInput() { }); } -/** - * this clears the output buffer. It does not clear what the user sees on their screen. - * It also clears all of the ace error annotations. - */ -export function clearOutput() { - const stdOut = document.querySelector('.stdout'); - stdOut.innerHTML = ''; -} - -export function clearErrors() { - annotationsBuffer = []; - errorOutput = ""; - blockErrorsBuffer = {}; - markersBuffer.forEach((markerId) => { - textEditor.session.removeMarker(markerId); - }); -} - /** * This is a unique function that will throw a compiling error. This is commonly used for * lexing and parsing errors so that the correct tree is inferred but there is an error thrown for bad syntax. @@ -200,12 +179,6 @@ export function defaultError(message) { errorOutput += `${message}

We have not written an error message for this issue yet.`; } -export function addBlockErrors(workspace) { - for (var key in blockErrorsBuffer) { - var block = workspace.getBlockById(key); - block.setWarningText(blockErrorsBuffer[key]); - } -} /** * This will highlight a line of code @@ -230,7 +203,6 @@ export function highlightAstNode(environment, node) { environment.global.blocklyWorkspace.highlightBlock(node.blockID); } - markersBuffer.push(markerId); return markerId; } diff --git a/src/main.js b/src/main.js index 2c7ed5f..72c548c 100644 --- a/src/main.js +++ b/src/main.js @@ -17,7 +17,7 @@ import { text2tree } from './text2tree'; import { generateUrl, loadFromUrl } from './share'; import { codeText } from './examples'; -import { DEV_LOG, debugButton, addBlockErrors, annotationsBuffer, clearErrors, clearOutput, defaultError, errorOutput, getDebugMode, setDebugMode, setStepInto, stepButton, stepIntoButton, stopButton, textEditor, setStopClicked } from './common'; +import { DEV_LOG, debugButton, defaultError, errorOutput, getDebugMode, setDebugMode, setStepInto, stepButton, stepIntoButton, stopButton, textEditor, setStopClicked } from './common'; import { hideDebug, showDebug } from './debugger'; let runButton; @@ -33,7 +33,6 @@ let blockPane; let textPane; let stdOut; let stdErr; -let clearOut; let examples; let titleRefresh; @@ -86,7 +85,6 @@ function initializeGlobals() { textPane = document.querySelector('#aceCode'); stdOut = document.querySelector('.stdout'); stdErr = document.querySelector('.stderr'); - clearOut = document.querySelector('.clearOut'); bottomPart = document.getElementById('bottom-part'); resizeBarBott = document.querySelector('.resizeBarBott'); resizeSideInEmbed = document.querySelector('.resize-side-view'); @@ -177,7 +175,6 @@ function registerListeners() { } runButton.addEventListener('click', runTasks); - clearOut.addEventListener('click', clear); resetButton.addEventListener('click', showResetModal); workspace.addChangeListener(onBlocklyChange); @@ -400,9 +397,8 @@ function generateTable() { // } function clear() { - clearOutput(); - // stdOut.innerHTML = ""; - clearErrors(); + errorOutput = ""; + stdOut.innerHTML = ""; stdErr.innerHTML = ""; varTable.innerHTML = ""; } @@ -494,10 +490,9 @@ async function runTasks() { } } if (errorOutput) { - textEditor.session.setAnnotations(annotationsBuffer); + // show the error, clear the buffer stdErr.innerHTML = errorOutput; - addBlockErrors(workspace); - clearErrors(); + errorOutput = ""; } else { // replace special chars if ran without error var pos = textEditor.getCursorPosition(); @@ -522,9 +517,6 @@ export function turnCodeToBlocks() { workspace.clear(); tree2blocks(workspace, mainTree); workspace.render(); - //comment this out to stop the live error feedback. - textEditor.session.setAnnotations(annotationsBuffer); - addBlockErrors(workspace); } function onBlocklyChange(event) { From 2d87735363aa13ec595779b0b7dfd69926c77b10 Mon Sep 17 00:00:00 2001 From: Chris Mayfield Date: Tue, 23 Jul 2024 14:12:51 -0400 Subject: [PATCH 11/33] rename addToPrintBuffer to consoleOutput (for consistency) --- src/ast.js | 4 ++-- src/common.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ast.js b/src/ast.js index 8fb9be7..edf283c 100644 --- a/src/ast.js +++ b/src/ast.js @@ -3,7 +3,7 @@ import { OP, NODETYPES, PraxlyError, - addToPrintBuffer, + consoleOutput, consoleInput, defaultError, errorOutput, @@ -538,7 +538,7 @@ class Praxly_print { suffix = '
'; } - addToPrintBuffer(result + suffix); + consoleOutput(result + suffix); return null; } } diff --git a/src/common.js b/src/common.js index 2cb07be..0b71afa 100644 --- a/src/common.js +++ b/src/common.js @@ -102,7 +102,7 @@ export class PraxlyError extends Error { export const MAX_LOOP = 100; // prevents accidental infinite loops export var errorOutput = ""; -export function addToPrintBuffer(message) { +export function consoleOutput(message) { const stdOut = document.querySelector('.stdout'); stdOut.insertAdjacentHTML('beforeend', message); } From c4e02a8518444ab51a000611b4bc7c5f58cb900d Mon Sep 17 00:00:00 2001 From: Chris Mayfield Date: Tue, 23 Jul 2024 16:10:29 -0400 Subject: [PATCH 12/33] rewrite runTasks to handle compile-time and run-time --- archive/errors.md | 2 - src/common.js | 60 +++++++++++----------- src/main.js | 123 +++++++++++++++++++++++++--------------------- 3 files changed, 99 insertions(+), 86 deletions(-) diff --git a/archive/errors.md b/archive/errors.md index 5fb1eee..bba79b7 100644 --- a/archive/errors.md +++ b/archive/errors.md @@ -59,5 +59,3 @@ Removed from `runTasks()` and `turnCodeToBlocks()`: textEditor.session.setAnnotations(annotationsBuffer); addBlockErrors(workspace); ``` - -Replaced `clearErrors()` with `errorOutput = "";`. diff --git a/src/common.js b/src/common.js index 0b71afa..ea1041b 100644 --- a/src/common.js +++ b/src/common.js @@ -1,6 +1,5 @@ import ace from 'ace-builds'; import './mode-praxly.js'; -import Blockly from 'blockly'; // this is going to be the place where all shared enums and constants. (this is the place for all shared enums and constants.) @@ -89,18 +88,42 @@ export const NODETYPES = { } -// this is the special Error type that is thrown when there is in error in the ide. +export var errorOutput = ""; // buffer for error messages (don't display until run) +export const MAX_LOOP = 100; // prevents accidental infinite loops + +// this is the special Error type that is thrown when there is in error in the IDE. export class PraxlyError extends Error { constructor(message, line) { - super(`
error occurred on line ${line}:\n\t${message}
`); - this.errorMessage = this.message; - errorOutput = this.message; // not appending run-time error + super(`runtime error occurred on line ${line}:\n\t${message}`); + textError("runtime", message, line); } } +/** + * This is commonly used for lexing and parsing errors so that the correct tree + * is inferred but there is an error displayed for bad syntax. + * @param {string} type the type of error + * @param {string} message the error message + * @param {number} line the error line number + */ +export function textError(type, message, line) { + if (errorOutput) { + errorOutput += "

"; + } + errorOutput += `${type} error occurred on line ${line}:\n\t${message}`; +} + +export function defaultError(message) { + if (errorOutput) { + errorOutput += "

"; + } + errorOutput += `${message}

We have not written an error message for this issue yet.`; +} + +export function clearErrors() { + errorOutput = ""; +} -export const MAX_LOOP = 100; // prevents accidental infinite loops -export var errorOutput = ""; export function consoleOutput(message) { const stdOut = document.querySelector('.stdout'); @@ -157,28 +180,6 @@ export function consoleInput() { }); } -/** - * This is a unique function that will throw a compiling error. This is commonly used for - * lexing and parsing errors so that the correct tree is inferred but there is an error thrown for bad syntax. - * @param {string} type the type of error - * @param {string} error the error message - * @param {number} line the error line number - */ -export function textError(type, error, line) { - if (errorOutput) { - errorOutput += "

"; - } - errorOutput += `${type} error occurred on line ${line}: ${error}`; - // appendAnnotation(error, line); -} - -export function defaultError(message) { - if (errorOutput) { - errorOutput += "

"; - } - errorOutput += `${message}

We have not written an error message for this issue yet.`; -} - /** * This will highlight a line of code @@ -254,6 +255,7 @@ export function getStopClicked() { return stopClicked; } + const isFirefox = navigator.userAgent.toLowerCase().includes('firefox'); const fontSize = isFirefox ? 18 : 16; diff --git a/src/main.js b/src/main.js index 72c548c..c75a958 100644 --- a/src/main.js +++ b/src/main.js @@ -14,10 +14,10 @@ import "ace-builds/src-min-noconflict/theme-dracula"; import "ace-builds/src-min-noconflict/theme-katzenmilch"; import { tree2blocks } from './tree2blocks'; import { text2tree } from './text2tree'; -import { generateUrl, loadFromUrl } from './share'; +import { generateUrl } from './share'; import { codeText } from './examples'; -import { DEV_LOG, debugButton, defaultError, errorOutput, getDebugMode, setDebugMode, setStepInto, stepButton, stepIntoButton, stopButton, textEditor, setStopClicked } from './common'; +import { DEV_LOG, debugButton, defaultError, errorOutput, getDebugMode, setDebugMode, setStepInto, stepButton, stepIntoButton, stopButton, textEditor, setStopClicked, clearErrors } from './common'; import { hideDebug, showDebug } from './debugger'; let runButton; @@ -128,7 +128,6 @@ function registerListeners() { shareButton.addEventListener('click', generateUrl); stepIntoButton.addEventListener('mouseup', function () { - // comingSoon(); if (!getDebugMode()) { endDebugPrompt(); } @@ -249,10 +248,7 @@ function registerListeners() { */ debugButton.addEventListener('mouseup', function () { - // comingSoon(); - showDebug(); - setDebugMode(true); - runTasks(); + runTasks(true); }); stopButton.addEventListener('click', function () { @@ -263,15 +259,6 @@ function registerListeners() { stepButton.click(); // in case awaiting }); - - // stepButton.addEventListener('mouseup', function () { - // // comingSoon(); - // if (!getDebugMode()) { - // endDebugPrompt(); - // } - // setDebugMode(true); - // }); - } @@ -397,7 +384,6 @@ function generateTable() { // } function clear() { - errorOutput = ""; stdOut.innerHTML = ""; stdErr.innerHTML = ""; varTable.innerHTML = ""; @@ -446,57 +432,80 @@ function refresh() { /** * this function gets called every time the run button is pressed. */ -async function runTasks() { +async function runTasks(startDebug) { + + // clear previous results clear(); - setStopClicked(false); await refresh(); + + // abort if compile-time error + if (errorOutput) { + stdErr.innerHTML = errorOutput; + return; + } + + // do nothing if code is blank + if (!textEditor.getValue().trim()) { + return; + } + + // if debug button was clicked + if (startDebug) { + showDebug(); + setDebugMode(true); + setStopClicked(false); + } + try { - // compile/run only if not blank - if (textEditor.getValue().trim()) { - const executable = createExecutable(mainTree); - - // This suggestion for the seed comes from the pure-rand - // documentation at https://github.com/dubzzz/pure-rand. - const seed = Date.now() ^ (Math.random() * 0x100000000); - const environment = { - name: 'global', - parent: "root", - variableList: {}, - functionList: {}, - random: { - seed, - generator: prand.xoroshiro128plus(seed), - }, - blocklyWorkspace: workspace, - }; - - // All scopes have a shortcut reference to the global scope. That - // way we can quickly find global data, like the random number - // generator, without having to iterate through the parent - // references. - environment.global = environment; - - await executable.evaluate(environment); - } + // Create executable version of the AST + const executable = createExecutable(mainTree); + + // This suggestion for the seed comes from the pure-rand + // documentation at https://github.com/dubzzz/pure-rand. + const seed = Date.now() ^ (Math.random() * 0x100000000); + + // Create initial environment for global variables + const environment = { + name: 'global', + parent: "root", + variableList: {}, + functionList: {}, + random: { + seed, + generator: prand.xoroshiro128plus(seed), + }, + blocklyWorkspace: workspace, + }; + + // All scopes have a shortcut reference to the global scope. That + // way we can quickly find global data, like the random number + // generator, without having to iterate through the parent references. + environment.global = environment; + + // Run the compiled program + await executable.evaluate(environment); + } catch (error) { if (error.message === "Stop_Debug") { // special case: abort running (not an error) clear(); - // exit debug, clear output/vars, restart debugger } else if (!errorOutput) { - // if not previously handled (by PraxlyError) + // error not previously handled (by PraxlyError) defaultError(error); console.error(error); } } + if (errorOutput) { - // show the error, clear the buffer + // run-time error; abort debugger stdErr.innerHTML = errorOutput; - errorOutput = ""; + if (getDebugMode()) { + stopButton.click(); + } } else { - // replace special chars if ran without error + // successful run; replace special chars var pos = textEditor.getCursorPosition(); - turnBlocksToCode(); + turnBlocksToCode(); // reformats the code textEditor.moveCursorToPosition(pos); textEditor.addEventListener("input", turnCodeToBlocks); } @@ -509,11 +518,14 @@ export function turnCodeToBlocks() { if (getDebugMode()) { stopButton.click(); } - mainTree = text2tree(); + // this is where lexing/parsing begins + clearErrors(); + mainTree = text2tree(); if (DEV_LOG) { console.log(mainTree); } + workspace.clear(); tree2blocks(workspace, mainTree); workspace.render(); @@ -530,8 +542,9 @@ function onBlocklyChange(event) { function turnBlocksToCode() { textEditor.removeEventListener("input", turnCodeToBlocks); mainTree = blocks2tree(workspace, praxlyGenerator); - // console.info("here is the tree generated by the blocks:"); - // console.debug(mainTree); + if (DEV_LOG) { + console.log(mainTree); + } const text = tree2text(mainTree, 0, 0); textEditor.setValue(text, -1); }; From 0f0e164d04d81459597bf2886c30b1deae22cd7d Mon Sep 17 00:00:00 2001 From: Chris Mayfield Date: Tue, 23 Jul 2024 16:26:22 -0400 Subject: [PATCH 13/33] make sure all PraxlyError include a line number --- src/ast.js | 17 ++++++++--------- src/text2tree.js | 15 +++++++-------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/ast.js b/src/ast.js index edf283c..40b9fe4 100644 --- a/src/ast.js +++ b/src/ast.js @@ -145,7 +145,7 @@ export function createExecutable(tree) { } else if (tree.name === 'float') { return new Praxly_float_conversion(createExecutable(tree.parameters[0]), tree); } else { - throw new Error('unknown builtin function'); + throw new Error("unknown builtin function: " + tree.name); } } @@ -474,7 +474,6 @@ class Praxly_array_literal { constructor(elements, node) { this.elements = elements; - this.node = node; this.json = node; this.jsonType = 'Praxly_array'; @@ -1467,7 +1466,7 @@ class Praxly_function_call { if (can_assign(parameterType, argument.realType, this.json.line)) { newScope.variableList[parameterName] = argument; } else { - throw new PraxlyError(`argument ${parameterName} does not match parameter type.\n\tExpected: ${parameterType}\n\tActual: ${argument.realType}`); + throw new PraxlyError(`argument ${parameterName} does not match parameter type.\n\tExpected: ${parameterType}\n\tActual: ${argument.realType}`, this.json.line); } } @@ -1505,20 +1504,20 @@ class Praxly_function_call { } class Praxly_String_funccall { - constructor(node, reciever, name, args) { + constructor(node, receiver, name, args) { this.args = args; - this.node = node; + this.json = node; this.name = name; - this.reciever = reciever + this.receiver = receiver; } typecheckhelper(argument, expected_types) { if (!expected_types.includes(argument.realType)) { - throw new PraxlyError(`argument ${parameterName} does not match parameter type.\n\tExpected: ${expected_type}\n\tActual: ${argument.realType}`); + throw new PraxlyError(`argument ${parameterName} does not match parameter type.\n\tExpected: ${expected_type}\n\tActual: ${argument.realType}`, this.json.line); } } async evaluate(environment) { - var str = await this.reciever.evaluate(environment); + var str = await this.receiver.evaluate(environment); var result; switch (this.name) { case StringFuncs.CHARAT: @@ -1550,7 +1549,7 @@ class Praxly_String_funccall { result = str.value.substring(startIndex.value, endIndex.value); return new Praxly_String(result); default: - throw new PraxlyError(`unrecognized function name ${this.name} for strings.`, this.node.line); + throw new PraxlyError(`unrecognized function name ${this.name} for strings.`, this.json.line); } } diff --git a/src/text2tree.js b/src/text2tree.js index 1212807..e4e7bce 100644 --- a/src/text2tree.js +++ b/src/text2tree.js @@ -566,7 +566,7 @@ class Parser { this.advance(); const r = this.parse_expression(precedence); if (r.type != NODETYPES.FUNCCALL) { - textError("compile-time", "classes are not fully supported yet. the right side of the . operator must be a supported string function", line); + textError('parsing', "classes are not fully supported yet. the right side of the . operator must be a supported string function", line); } l = { left: l, @@ -637,7 +637,7 @@ class Parser { } result.params = args; if (this.hasNot('}')) { - textError("parsing", "didn't detect closing curly brace in the array declaration", this.tokens[this.i].line); + textError('parsing', "didn't detect closing curly brace in the array declaration", this.tokens[this.i].line); } result.endIndex = this.getCurrentToken().endIndex; this.advance(); @@ -690,8 +690,7 @@ class Parser { // TODO: this case needs to raise an exception or return some error // object. Right now if an expression can't be parsed, it // implicitly returns null/undefined. - // throw new Error("couldn't parse expression"); - textError("parsing", `invalid Token ${this.getCurrentToken().value}`, line); + textError('parsing', `invalid Token ${this.getCurrentToken().value}`, line); } } } @@ -832,7 +831,7 @@ class Parser { var contents = this.parse_block('end ' + result.name); result.contents = contents; if (this.hasNot('end ' + result.name)) { - textError('compile time', `missing the \'end ${result.name}\' token`, result.line); + textError('parsing', `missing the \'end ${result.name}\' token`, result.line); result.endIndex = this.getCurrentToken().endIndex; return result; } @@ -918,7 +917,7 @@ class Parser { return result; } else { - textError('compile time', "missing the \'end if\' token", result.line); + textError('parsing', "missing the \'end if\' token", result.line); } } @@ -949,7 +948,7 @@ class Parser { return result; } else { - textError('compile time', "missing the \'end for\' token", result.line); + textError('parsing', "missing the \'end for\' token", result.line); } } } @@ -978,7 +977,7 @@ class Parser { this.advance(); return result; } else { - textError('compile time', "missing the \'end while\' token", result.line); + textError('parsing', "missing the \'end while\' token", result.line); } } From 0584913412d763d8e45818195e38c88d425bdc42 Mon Sep 17 00:00:00 2001 From: Chris Mayfield Date: Tue, 23 Jul 2024 16:38:40 -0400 Subject: [PATCH 14/33] reduce the number of console.error() calls --- src/ast.js | 22 +++++++++++----------- src/tree2blocks.js | 4 ---- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/ast.js b/src/ast.js index 40b9fe4..7daa6cb 100644 --- a/src/ast.js +++ b/src/ast.js @@ -190,7 +190,7 @@ export function createExecutable(tree) { return new Praxly_assignment(tree, createExecutable(tree.location), createExecutable(tree.value), tree); } catch (error) { - console.error('assignment error: ', error); + // console.error('assignment error: ', error); return null; } @@ -207,7 +207,7 @@ export function createExecutable(tree) { return new Praxly_array_assignment(tree, createExecutable(tree.location), createExecutable(tree.value)); } catch (error) { - console.error('assignment error: ', error); + // console.error('array assignment error: ', error); return null; } @@ -232,7 +232,7 @@ export function createExecutable(tree) { return new Praxly_for(initialization, condition, incrementation, statement, tree); } catch (error) { - console.error(error); + // console.error('for statement error: ', error); return new Praxly_statement(null); } @@ -243,7 +243,7 @@ export function createExecutable(tree) { return new Praxly_while(condition, statement, tree); } catch (error) { - console.error(error); + // console.error('while statement error: ', error); return new Praxly_statement(null); } @@ -254,7 +254,7 @@ export function createExecutable(tree) { return new Praxly_do_while(condition, statement, tree); } catch (error) { - console.error('An error occurred: empty statement', error); + // console.error('do while statement error: ', error); return new Praxly_statement(null); } @@ -265,7 +265,7 @@ export function createExecutable(tree) { return new Praxly_repeat_until(condition, statement, tree); } catch (error) { - console.error('An error occurred: empty statement', error); + // console.error('repeat until statement error: ', error); return new Praxly_statement(null); } @@ -315,7 +315,8 @@ export function createExecutable(tree) { return new Praxly_emptyLine(tree); default: - console.error(`I don't recognize this type: ${tree.type}}`); + console.error("Unhandled node type: " + tree.type); + return new Praxly_invalid(tree); } } @@ -1046,7 +1047,7 @@ function typeCoercion(varType, praxlyObj) { newValue = String(praxlyObj.value); return new Praxly_String(newValue, praxlyObj.json); default: - console.error("Unhandled varType:" + varType); + console.error("Unhandled var type: " + varType); return praxlyObj; } } @@ -1124,7 +1125,7 @@ class Praxly_vardecl { valueEvaluated = new Praxly_String(""); break; default: - console.error("Unhandled varType:" + this.json.varType); + console.error("Unhandled var type: " + this.json.varType); break; } } @@ -1772,8 +1773,7 @@ function litNode_new(type, value, json) { case TYPES.SHORT: return new Praxly_short(value); case TYPES.INVALID: - console.error(`invalid literal:`); - console.error(json); + console.error("Invalid literal: ", json); return new Praxly_invalid(); } } diff --git a/src/tree2blocks.js b/src/tree2blocks.js index 8bf9923..1fe9a70 100644 --- a/src/tree2blocks.js +++ b/src/tree2blocks.js @@ -341,11 +341,8 @@ export const tree2blocks = (workspace, node) => { case NODETYPES.FOR: var result = workspace.newBlock('praxly_for_loop_block'); - - //gohere try { var initialization = tree2blocks(workspace, node?.initialization); - // console.error(initialization?.type); if (!initialization || initialization.type !== 'praxly_statement_block') { initialization.dispose(); var initialization = workspace.newBlock('praxly_assignment_expression_block'); @@ -399,7 +396,6 @@ export const tree2blocks = (workspace, node) => { case NODETYPES.ARRAY_REFERENCE_ASSIGNMENT: var result = workspace.newBlock('praxly_array_reference_reassignment_block'); - console.error(`reached here`); result.setFieldValue(node.name, "VARIABLENAME"); var child = tree2blocks(workspace, node?.index); result.getInput('INDEX').connection.connect(child?.outputConnection); From 69baf73524713c566cb18190a30a74d0353700e4 Mon Sep 17 00:00:00 2001 From: Chris Mayfield Date: Tue, 23 Jul 2024 16:49:59 -0400 Subject: [PATCH 15/33] improve missing close quote in string literal --- src/text2tree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text2tree.js b/src/text2tree.js index e4e7bce..1be75e4 100644 --- a/src/text2tree.js +++ b/src/text2tree.js @@ -177,7 +177,7 @@ class Lexer { if (this.has("\"")) { var stringStart = this.currentLine; this.skip(); - while (this.i < this.length && !this.has("\"")) { + while (this.i < this.length && !this.has("\"") && !this.has("\n")) { this.capture(); } if (this.has("\"")) { From a0bdbfc64f97059a3481f876a3da1e69b7330599 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Tue, 23 Jul 2024 17:07:13 -0400 Subject: [PATCH 16/33] Add print as keyword. --- src/mode-praxly.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mode-praxly.js b/src/mode-praxly.js index 1292492..af02862 100644 --- a/src/mode-praxly.js +++ b/src/mode-praxly.js @@ -933,7 +933,7 @@ var JavaHighlightRules = function () { "char|final|interface|static|void|" + "class|finally|long|strictfp|volatile|" + "const|float|native|super|while|end|" + - "var|and|or|not|repeat|until"); + "var|print|and|or|not|repeat|until"); var buildinConstants = ("null|Infinity|NaN|undefined"); var langClasses = ("AbstractMethodError|AssertionError|ClassCircularityError|" + "ClassFormatError|Deprecated|EnumConstantNotPresentException|" + From a4f34b352bf07048671b9b687716767313c87974 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Tue, 23 Jul 2024 17:24:30 -0400 Subject: [PATCH 17/33] Add typechecking to casts. --- src/ast.js | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/ast.js b/src/ast.js index 624fa8f..8870e45 100644 --- a/src/ast.js +++ b/src/ast.js @@ -594,7 +594,7 @@ class Praxly_random_int { async evaluate(environment) { const maxNode = (await this.max.evaluate(environment)); - if (maxNode.realType === 'int') { + if (maxNode.realType === TYPES.INT) { const maxValue = maxNode.value; const x = prand.unsafeUniformIntDistribution(0, maxValue - 1, environment.global.random.generator); return new Praxly_int(x, this.json); @@ -612,7 +612,7 @@ class Praxly_random_seed { async evaluate(environment) { const seedNode = (await this.seed.evaluate(environment)); - if (seedNode.realType === 'int') { + if (seedNode.realType === TYPES.INT) { const seedValue = seedNode.value; environment.global.random.seed = seedValue; environment.global.random.generator = prand.xoroshiro128plus(seedValue); @@ -630,10 +630,24 @@ class Praxly_int_conversion { } async evaluate(environment) { - let valueEvaluated = await this.value.evaluate(environment); - // value is likely a Praxly_String; get the actual string - const convert = new Praxly_int(valueEvaluated.value); - return convert; + let node = await this.value.evaluate(environment); + if (node.realType === TYPES.INT) { + const convert = new Praxly_int(node.value); + return convert; + } else if (node.realType === TYPES.DOUBLE || node.realType === TYPES.FLOAT) { + const convert = new Praxly_int(Math.trunc(node.value)); + return convert; + } else if (node.realType === TYPES.STRING) { + const number = Number(node.value); + if (isNaN(number)) { + throw new PraxlyError(`"${node.value}" cannot be converted to an int.`, this.json.line); + } else { + const convert = new Praxly_int(number); + return convert; + } + } else { + throw new PraxlyError(`Function int doesn't accept a parameter of type ${node.realType}.`, this.json.line); + } } } @@ -644,10 +658,24 @@ class Praxly_float_conversion { } async evaluate(environment) { - let valueEvaluated = await this.value.evaluate(environment); - // value is likely a Praxly_String; get the actual string - const convert = new Praxly_float(valueEvaluated.value); - return convert; + let node = await this.value.evaluate(environment); + if (node.realType === TYPES.DOUBLE || node.realType === TYPES.FLOAT) { + const convert = new Praxly_float(node.value); + return convert; + } else if (node.realType === TYPES.INT) { + const convert = new Praxly_float(node.value); + return convert; + } else if (node.realType === TYPES.STRING) { + const number = Number(node.value); + if (isNaN(number)) { + throw new PraxlyError(`"${node.value}" cannot be converted to a float.`, this.json.line); + } else { + const convert = new Praxly_float(number); + return convert; + } + } else { + throw new PraxlyError(`Function float doesn't accept a parameter of type ${node.realType}.`, this.json.line); + } } } From 61ec528e67343e8d5c24fb7084b38ec94d4611dc Mon Sep 17 00:00:00 2001 From: ellonamac Date: Wed, 24 Jul 2024 12:26:29 -0400 Subject: [PATCH 18/33] fixed report button and all members added --- index.html | 9 +++---- public/index.css | 46 ++++++++++++++++++------------------ public/people/macmillan.png | Bin 0 -> 3127399 bytes 3 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 public/people/macmillan.png diff --git a/index.html b/index.html index 95a5962..18ecaf2 100644 --- a/index.html +++ b/index.html @@ -13,9 +13,9 @@ -
+

Welcome to Praxly 🍂

@@ -34,6 +34,7 @@

Welcome to Praxly 🍂

+