JSFiddle - React, Tailwind, and code Playground

by Ben Gillbanks

HTML

<script src="https://unpkg.com/[email protected]/dist/ohm.min.js"></script>
<!DOCTYPE html>
<html>
<head>
  <title>Logo-style Language Interpreter</title>
<script id="grammar" type="ohm/grammar">
  Logo {
    sourceCharacter = any
    lineTerminator = "\n" | "\r" | "\u2028" | "\u2029"
    whitespace = "\t"
             | "\x0B"    -- verticalTab
             | "\x0C"    -- formFeed
             | " "
             | "\u00A0"  -- noBreakSpace
             | "\uFEFF"  -- byteOrderMark
             | unicodeSpaceSeparator
    unicodeSpaceSeparator = "\u2000".."\u200B" | "\u3000"
    start = commandList
    commandList = command (space command)*
    command = move | turn | draw
    num = "-"? digit+
    move = "MOVE" num
    turn = "TURN" num
    draw = "DRAW"
    space := whitespace | lineTerminator | comment
    comment = "//" (~lineTerminator sourceCharacter)*
  }
</script>
</head>
<body>
  <textarea id="userInput" rows="10" cols="50">MOVE 50
TURN 90
DRAW
</textarea>
  <br>
  <button onclick="interpretInput()">Interpret</button>
</body>
</html>

JavaScript

const logoGrammar = document.querySelector('#grammar').textContent;


const logoParser = ohm.grammar(logoGrammar);

function interpretInput() {

    const userInput = document.getElementById('userInput').value.trim();
    
    if ( !userInput ) { return; }
    
    const match = logoParser.match(userInput);
    
    console.log(match.message);
//    console.log(userInput, match);

//      const semantics = logoParser.createSemantics();
      

    if (match.succeeded()) {
      // Input is valid
      const semantics = logoParser.createSemantics();
      // Define actions for different commands
      semantics.addOperation('interpret', {
        move(_, num) {
          return `Move forward ${Number(num)}`;
        },
        turn(_, num) {
          return `Turn ${Number(num)} degrees`;
        },
        draw(_, num) {
          return `Draw a line of length ${Number(num)}`;
        },
      });

      const output = semantics(match).interpret();
      console.log(output); // You can display this output on the screen or perform other actions.
    } else {
      // Input is not valid
      console.log('Invalid input');
    }

}