Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Whiley Lexer #628

Merged
merged 3 commits into from Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 57 additions & 0 deletions lexers/embedded/whiley.xml
@@ -0,0 +1,57 @@
<lexer>
<config>
<name>Whiley</name>
<alias>whiley</alias>
<filename>*.whiley</filename>
<mime_type>text/x-whiley</mime_type>
</config>
<rules>
<state name="root">
<rule pattern="\n">
<token type="Text"/>
</rule>
<rule pattern="\s+">
<token type="Text"/>
</rule>
<rule pattern="\\\n">
<token type="Text"/>
</rule>
<rule pattern="/[*](.|\n)*?[*]/">
<token type="CommentMultiline"/>
</rule>
<rule pattern="//.*?\n">
<token type="CommentSingle"/>
</rule>
<rule pattern="(function|import|from|method|property|type|with|variant)\b">
<token type="KeywordDeclaration"/>
</rule>
<rule pattern="(assert|assume|all|break|case|continue|debug|default|do|else|ensures|export|fail|final|for|if|in|is|native|no|new|private|protected|public|return|requires|skip|some|switch|unsafe|where|while)\b">
<token type="Keyword"/>
</rule>
<rule pattern="(true|false|null)\b">
<token type="KeywordConstant"/>
</rule>
<rule pattern="(bool|byte|int|void)\b">
<token type="KeywordType"/>
</rule>
<rule pattern="0b(?:_?[01])+">
<token type="LiteralNumberBin"/>
</rule>
<rule pattern="0[xX][0-9a-fA-F]+">
<token type="LiteralNumberHex"/>
</rule>
<rule pattern="(0|[1-9][0-9]*)">
<token type="LiteralNumberInteger"/>
</rule>
<rule pattern="[a-zA-Z_]\w*">
<token type="Name"/>
</rule>
<rule pattern="[+%=&gt;&lt;|^!?/\-*&amp;~:]">
<token type="Operator"/>
</rule>
<rule pattern="[{}()\[\],.;\|]">
<token type="Punctuation"/>
</rule>
</state>
</rules>
</lexer>
76 changes: 76 additions & 0 deletions lexers/testdata/whiley.actual
@@ -0,0 +1,76 @@

import uint from std::integer
import uinteger from js::core
import random from js::math
import Document, Window, CanvasRenderingContext2D from w3c::dom
import Element,HTMLCanvasElement, HTMLImageElement, MouseEvent from w3c::dom

import model
import view

/**
* Add a given number of bombs to the board.
*/
method add_random_bombs(model::Board board, uint n) -> model::Board:
uinteger remaining = |board.squares|
// Use Knuth's algorithm S
for x in 0..board.width:
for y in 0..board.height:
// Flip a coin (so-to-speak)
if random(remaining) < n:
// create bomb square
model::Square s = model::HiddenSquare(true,false)
// Update board
board = model::set_square(board,(uint) x, (uint) y,s)
// Reduce number of bombs to place
n = n - 1
// Reduce remaining options
remaining = remaining - 1
// return updated board
return board

/**
* Handle a mouse event on the canvas
*/
method onclick_handler(MouseEvent e, &view::State state, Window window):
// Convert from view to world coordinates
uint x = e->offsetX / state->gridsize
uint y = e->offsetY / state->gridsize
// Update board
if e->shiftKey:
state->board = model::flag_square(state->board,x,y)
else:
state->board = model::expose_square(state->board,x,y)
// Render initial board
view::draw_board(*state)
// Finally determine game status
(bool gameOver, bool winner) = model::is_gameover(state->board)
// Check whether game over
if gameOver:
// Yes, but win or lose?
if winner:
window->alert("Well done --- You Found all the Mines!")
else:
window->alert("Game Over --- You Lost!")
// Done

/**
* Create a new game of Minesweeper
*/
public export method main(uint width, uint height, uint bombs, Window window, HTMLCanvasElement canvas, HTMLImageElement[] images)
// Requires at least 9 images
requires |images| == 13:
Document document = window->document
// NOTE: following should not be required!
Element c = document->getElementById("myCanvas")
// Create a standard sized board
model::Board board = model::Board(width,height)
// Add bombs
board = add_random_bombs(board,bombs)
// Initialise the view state
&view::State state = new view::init(document,canvas,board,images)
// Render initial board
view::draw_board(*state)
// Configure mouse click listener
c->addEventListener("click",&(MouseEvent e -> onclick_handler(e,state,window)))