forked from rouge-ruby/rouge
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request rouge-ruby#651 from katafrakt/pony
Add lexer for Pony
- Loading branch information
Showing
4 changed files
with
308 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
use "ponytest" | ||
|
||
actor Main is TestList | ||
new create(env: Env) => PonyTest(env, this) | ||
new make() => None | ||
|
||
fun tag tests(test: PonyTest) => | ||
test(_TestAddition) | ||
|
||
class iso _TestAddition is UnitTest | ||
""" | ||
Adding 2 numbers | ||
""" | ||
fun name(): String => "u32/add" | ||
|
||
fun apply(h: TestHelper): TestResult => | ||
h.expect_eq[U32](2 + 2, 4) |
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,93 @@ | ||
# -*- coding: utf-8 -*- # | ||
|
||
module Rouge | ||
module Lexers | ||
class Pony < RegexLexer | ||
tag 'pony' | ||
filenames '*.pony' | ||
|
||
keywords = %w( | ||
actor addressof and as | ||
be break | ||
class compiler_intrinsic consume continue | ||
do | ||
else elseif embed end error | ||
for fun | ||
if ifdef in interface is isnt | ||
lambda let | ||
match | ||
new not | ||
object | ||
primitive | ||
recover repeat return | ||
struct | ||
then this trait try type | ||
until use | ||
var | ||
where while with | ||
) | ||
|
||
capabilities = %w( | ||
box iso ref tag trn val | ||
) | ||
|
||
types = %w( | ||
Number Signed Unsigned Float | ||
I8 I16 I32 I64 I128 U8 U32 U64 U128 F32 F64 | ||
EventID Align IntFormat NumberPrefix FloatFormat | ||
Type | ||
) | ||
|
||
state :whitespace do | ||
rule /[\s\t\r\n]+/m, Text | ||
end | ||
|
||
state :root do | ||
mixin :whitespace | ||
rule /"""/, Str::Doc, :docstring | ||
rule %r{//(.*?)\n}, Comment::Single | ||
rule %r{/(\\\n)?[*](.|\n)*?[*](\\\n)?/}, Comment::Multiline | ||
rule /"/, Str, :string | ||
rule %r([~!%^&*+=\|?:<>/-]), Operator | ||
rule /(true|false|NULL)\b/, Name::Constant | ||
rule %r{(?:[A-Z_][a-zA-Z0-9_]*)}, Name::Class | ||
rule /[()\[\],.';]/, Punctuation | ||
|
||
# Numbers | ||
rule /0[xX]([0-9a-fA-F_]*\.[0-9a-fA-F_]+|[0-9a-fA-F_]+)[pP][+\-]?[0-9_]+[fFL]?[i]?/, Num::Float | ||
rule /[0-9_]+(\.[0-9_]+[eE][+\-]?[0-9_]+|\.[0-9_]*|[eE][+\-]?[0-9_]+)[fFL]?[i]?/, Num::Float | ||
rule /\.(0|[1-9][0-9_]*)([eE][+\-]?[0-9_]+)?[fFL]?[i]?/, Num::Float | ||
rule /0[xX][0-9a-fA-F_]+/, Num::Hex | ||
rule /(0|[1-9][0-9_]*)([LUu]|Lu|LU|uL|UL)?/, Num::Integer | ||
|
||
rule /[a-z_][a-z0-9_]*/io do |m| | ||
match = m[0] | ||
|
||
if capabilities.include?(match) | ||
token Keyword::Declaration | ||
elsif keywords.include?(match) | ||
token Keyword::Reserved | ||
elsif types.include?(match) | ||
token Keyword::Type | ||
else | ||
token Name | ||
end | ||
end | ||
end | ||
|
||
state :string do | ||
rule /"/, Str, :pop! | ||
rule /\\([\\abfnrtv"']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})/, Str::Escape | ||
rule /[^\\"\n]+/, Str | ||
rule /\\\n/, Str | ||
rule /\\/, Str # stray backslash | ||
end | ||
|
||
state :docstring do | ||
rule /"""/, Str::Doc, :pop! | ||
rule /\n/, Str::Doc | ||
rule /./, Str::Doc | ||
end | ||
end | ||
end | ||
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,13 @@ | ||
# -*- coding: utf-8 -*- # | ||
|
||
describe Rouge::Lexers::Pony do | ||
let(:subject) { Rouge::Lexers::Pony.new } | ||
|
||
describe 'guessing' do | ||
include Support::Guessing | ||
|
||
it 'guesses by filename' do | ||
assert_guess :filename => 'foo.pony' | ||
end | ||
end | ||
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,185 @@ | ||
/* | ||
This file is copied from official Pony examples at: | ||
https://github.com/ponylang/ponyc/blob/master/examples/mandelbrot/mandelbrot.pony | ||
*/ | ||
|
||
use "files" | ||
use "options" | ||
use "collections" | ||
|
||
actor Worker | ||
new mandelbrot(main: Main, x: USize, y: USize, width: USize, | ||
iterations: USize, limit: F32, real: Array[F32] val, | ||
imaginary: Array[F32] val) | ||
=> | ||
var view: Array[U8] iso = | ||
recover | ||
Array[U8]((y - x) * (width >> 3)) | ||
end | ||
|
||
let group_r = Array[F32].>undefined(8) | ||
let group_i = Array[F32].>undefined(8) | ||
|
||
var row = x | ||
|
||
try | ||
while row < y do | ||
let prefetch_i = imaginary(row) | ||
|
||
var col: USize = 0 | ||
|
||
while col < width do | ||
var j: USize = 0 | ||
|
||
while j < 8 do | ||
group_r.update(j, real(col + j)) | ||
group_i.update(j, prefetch_i) | ||
j = j + 1 | ||
end | ||
|
||
var bitmap: U8 = 0xFF | ||
var n = iterations | ||
|
||
repeat | ||
var mask: U8 = 0x80 | ||
var k: USize = 0 | ||
|
||
while k < 8 do | ||
let r = group_r(k) | ||
let i = group_i(k) | ||
|
||
group_r.update(k, ((r * r) - (i * i)) + real(col + k)) | ||
group_i.update(k, (2.0 * r * i) + prefetch_i) | ||
|
||
if ((r * r) + (i * i)) > limit then | ||
bitmap = bitmap and not mask | ||
end | ||
|
||
mask = mask >> 1 | ||
k = k + 1 | ||
end | ||
until (bitmap == 0) or ((n = n - 1) == 1) end | ||
|
||
view.push(bitmap) | ||
|
||
col = col + 8 | ||
end | ||
row = row + 1 | ||
end | ||
|
||
main.draw(x * (width >> 3), consume view) | ||
end | ||
|
||
actor Main | ||
var iterations: USize = 50 | ||
var limit: F32 = 4.0 | ||
var chunks: USize = 16 | ||
var width: USize = 16000 | ||
var actors: USize = 0 | ||
var header: USize = 0 | ||
var real: Array[F32] val = recover Array[F32] end | ||
var imaginary: Array[F32] val = recover Array[F32] end | ||
var outfile: (File | None) = None | ||
|
||
new create(env: Env) => | ||
try | ||
arguments(env) | ||
|
||
let length = width | ||
let recip_width = 2.0 / width.f32() | ||
|
||
var r = recover Array[F32](length) end | ||
var i = recover Array[F32](length) end | ||
|
||
for j in Range(0, width) do | ||
r.push((recip_width * j.f32()) - 1.5) | ||
i.push((recip_width * j.f32()) - 1.0) | ||
end | ||
|
||
real = consume r | ||
imaginary = consume i | ||
|
||
spawn_actors() | ||
create_outfile() | ||
end | ||
|
||
be draw(offset: USize, pixels: Array[U8] val) => | ||
match outfile | ||
| let out: File => | ||
out.seek_start(header + offset) | ||
out.write(pixels) | ||
if (actors = actors - 1) == 1 then | ||
out.dispose() | ||
end | ||
end | ||
|
||
fun ref create_outfile() => | ||
match outfile | ||
| let f: File => | ||
f.print("P4\n " + width.string() + " " + width.string() + "\n") | ||
header = f.size() | ||
f.set_length((width * (width >> 3)) + header) | ||
end | ||
|
||
fun ref spawn_actors() => | ||
actors = ((width + (chunks - 1)) / chunks) | ||
|
||
var rest = width % chunks | ||
|
||
if rest == 0 then rest = chunks end | ||
|
||
var x: USize = 0 | ||
var y: USize = 0 | ||
|
||
for i in Range(0, actors - 1) do | ||
x = i * chunks | ||
y = x + chunks | ||
Worker.mandelbrot(this, x, y, width, iterations, limit, real, imaginary) | ||
end | ||
|
||
Worker.mandelbrot(this, y, y + rest, width, iterations, limit, real, | ||
imaginary) | ||
|
||
fun ref arguments(env: Env) ? => | ||
let options = Options(env.args) | ||
|
||
options | ||
.add("iterations", "i", I64Argument) | ||
.add("limit", "l", F64Argument) | ||
.add("chunks", "c", I64Argument) | ||
.add("width", "w", I64Argument) | ||
.add("output", "o", StringArgument) | ||
|
||
for option in options do | ||
match option | ||
| ("iterations", let arg: I64) => iterations = arg.usize() | ||
| ("limit", let arg: F64) => limit = arg.f32() | ||
| ("chunks", let arg: I64) => chunks = arg.usize() | ||
| ("width", let arg: I64) => width = arg.usize() | ||
| ("output", let arg: String) => | ||
outfile = try File(FilePath(env.root as AmbientAuth, arg)) end | ||
| let err: ParseError => err.report(env.out) ; usage(env) ; error | ||
end | ||
end | ||
|
||
fun tag usage(env: Env) => | ||
env.out.print( | ||
""" | ||
mandelbrot [OPTIONS] | ||
The binary output can be converted to a BMP with the following command | ||
(ImageMagick Tools required): | ||
convert <output> JPEG:<output>.jpg | ||
Available options: | ||
--iterations, -i Maximum amount of iterations to be done for each pixel. | ||
Defaults to 50. | ||
--limit, -l Square of the limit that pixels need to exceed in order | ||
to escape from the Mandelbrot set. | ||
Defaults to 4.0. | ||
--chunks, -c Maximum line count of chunks the image should be | ||
divided into for divide & conquer processing. | ||
Defaults to 16. | ||
--width, -w Lateral length of the resulting mandelbrot image. | ||
Defaults to 16000. | ||
--output, -o File to write the output to. | ||
""" | ||
) |