Skip to content

Commit

Permalink
Add Lustre lexer (#905)
Browse files Browse the repository at this point in the history
This commit adds a lexer for the Lustre language.
  • Loading branch information
jahierwan authored and pyrmont committed Aug 23, 2019
1 parent 6ad8346 commit e84edc4
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/rouge/demos/lustre
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node count(init: int; reset, event: bool) returns (c: int);
let
c = init -> if reset then init
else if event then pre(c)+1
else pre(c);
tel;
80 changes: 80 additions & 0 deletions lib/rouge/lexers/lustre.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*- #
#
# adapted from ocaml.rb, hence some ocaml-ism migth remains
module Rouge
module Lexers
class Lustre < RegexLexer
title "Lustre"
desc 'The Lustre programming language (Verimag)'
tag 'lustre'
filenames '*.lus'
mimetypes 'text/x-lustre'

def self.keywords
@keywords ||= Set.new %w(
extern unsafe assert const current enum function
let node operator returns
step struct tel type var model package needs
provides uses is body end include merge
)
end

def self.word_operators
@word_operators ||= Set.new %w(
div and xor mod or not nor if then else fby pre when with)
end

def self.primitives
@primitives ||= Set.new %w(int real bool)
end

operator = %r([,!$%&*+./:<=>?@^|~#-]+)
id = /[a-z_][\w']*/i

state :root do
rule (/\s+/m), Text
rule (/false|true/), Keyword::Constant
rule %r(\-\-.*), Comment::Single
rule %r(/\*.*?\*/)m, Comment::Multiline
rule %r(\(\*.*?\*\))m, Comment::Multiline
rule id do |m|
match = m[0]
if self.class.keywords.include? match
token Keyword
elsif self.class.word_operators.include? match
token Operator::Word
elsif self.class.primitives.include? match
token Keyword::Type
else
token Name
end
end

rule (/[(){}\[\];]+/), Punctuation
rule operator, Operator

rule (/-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i), Num::Float
rule (/\d[\d_]*/), Num::Integer

rule (/'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/), Str::Char
rule (/'[.]'/), Str::Char
rule (/"/), Str::Double, :string
rule (/[~?]#{id}/), Name::Variable
end

state :string do
rule (/[^\\"]+/), Str::Double
mixin :escape_sequence
rule (/\\\n/), Str::Double
rule (/"/), Str::Double, :pop!
end

state :escape_sequence do
rule (/\\[\\"'ntbr]/), Str::Escape
rule (/\\\d{3}/), Str::Escape
rule (/\\x\h{2}/), Str::Escape
end

end
end
end
18 changes: 18 additions & 0 deletions spec/lexers/lustre_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*- #

describe Rouge::Lexers::Lustre do
let(:subject) { Rouge::Lexers::Lustre.new }

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.lus'
end

it 'guesses by mimetype' do
assert_guess :mimetype => 'text/x-lustre'
end
end
end

49 changes: 49 additions & 0 deletions spec/visual/samples/lustre
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-------------------------------------------------------------------

-- Constants
const size = 50; -- size of the sliding windows used to smooth values
const period = 0.1; -- in seconds
const speed_max = 110.0; -- comment with leading whitespace

-- Types
type roof_state = enum { locked, in_motion };

type update_acc = {
i: int;
j: int;
v: real
};

-- Nodes
node roof(Tick, Parked, OnOff, Done: bool) returns (Locked:bool; Roof_Speed:real);
var
pst, st : roof_state;
Tick_on_in_motion : bool when in_motion(st);
let
pst = locked fby st;
st = merge pst
(locked -> if (OnOff and Parked) when locked(pst) then in_motion else locked)
(in_motion -> if Done when in_motion(pst) then locked else in_motion);
Locked = (st=locked) ;
Tick_on_in_motion = Tick when in_motion(st);
Roof_Speed = merge st
(locked -> 0.0 when locked(st))
(in_motion -> roof_speed(Tick_on_in_motion));
tel

node sum<<const d: int; const init:real>>(s: real) returns (res:real);
var
a,pre_a: real^d; -- circular array
i: int;
let
i = 0 fby i + 1;
pre_a = (init^d) fby a;
a = assign<<d>>(s, i mod d, pre_a);
res =red<<+; d>>(0.0, a); --- / Lustre::int2real(d) ;
tel

-- Functions
function braking_time(Speed:real) returns (res:real);
let
res = Speed * Speed / k;
tel

0 comments on commit e84edc4

Please sign in to comment.