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 Turing support #710

Closed
wants to merge 5 commits into from
Closed
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
38 changes: 38 additions & 0 deletions lib/rouge/demos/turing
@@ -0,0 +1,38 @@
var myStr : string := "hello"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please trim this down a bit. It's meant to be a small visual demo of what the lexer does, not of the language per se, for use e.g. on http://rouge.jneen.net/ - Most are 10-25 lines or so.


put(myStr) % Print myStr.
put(myStr(1)) % Print the first character in myStr.
put(myStr(*)) % Print the last character in myStr.
put(myStr(* - 1)) % Print the second last character in myStr.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

var original : string := "123" % This is the string we will reverse.
var reversed : string := "" % Create an empty string. We will add the characters in reverse order next.

for decreasing i : length (original) .. 1 % Loop through the original string backwards.
reversed += original(i) % Add the characters one by one.
end for

put(original + " backwards is: " + reversed) % Print the final result.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

var age : int

put "Please enter your age: "
get age

if age < 18 then
put "You are not an adult."
else
put "You are an adult."
end if

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

var startTime, endTime : int % Declare the two variables to keep track of time.
startTime := Time.Sec % Set startTime to the number of seconds since the start of the universe (1970).
delay(5000) % Wait 5 seconds.
endTime := Time.Sec % Set endTime to the number of seconds since the start of the universe (1970).
put(endTime - startTime) % Output the difference between startTime and endTime.
164 changes: 164 additions & 0 deletions lib/rouge/lexers/turing.rb
@@ -0,0 +1,164 @@
# -*- coding: utf-8 -*- #

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add '# frozen_string_literal: true'

module Rouge
module Lexers
class Turing < RegexLexer
title "Turing"
desc "The Turing programming language (http://compsci.ca/holtsoft/)"
tag 'turing'
filenames '*.t', '*.tu'

def self.analyze_text(text)
return 0.9 if text =~ /whatdotcolour\s*\(|whatdotcolor\s*\(|drawmapleleaf\s*\(|drawfillmapleleaf\s*\(/
end

methods = %w(
abs addr arctan arctand anyclass
break buttonchoose buttonmoved buttonwait ceil
chr clock cls color colorback
colour colourback cos cosd date
delay drawarc drawbox drawdot drawfill
drawfillarc drawfillbox drawfillmapleleaf drawfilloval drawfillpolygon
drawfillstar drawline drawmapleleaf drawoval drawpic
drawpolygon drawstar empty eof erealstr
exp fetcharg floor frealstr getch
getchar getenv getpid getpriority hasch
index intreal intstr length ln
locate locatexy lower max maxcol
maxcolor maxcolour maxint maxnat maxrow
maxx maxy min minint minnat
mousehide mouseshow mousewhere nargs natreal
natstr nil ord palette play
playdone pred rand randint randnext
randomize randseed realstr repeat round
setpriority setscreen sign simutime sin
sind sizeof sizepic sound sqrt
strint strintok strnat strnatok strreal
strrealok succ sysclock sysexit system
takepic time upper wallclock whatcol
whatcolor whatcolorback whatcolour whatcolourback whatdotcolor
whatdotcolour whatpalette whatrow whattextchar whattextcolor
whattextcolorback whattextcolour whattextcolourback
)

modules = %w(
Brush Button CheckBox Comm Concurrency
Config Dir Draw DropBox EditBox
Error ErrorNum Event File Font
GUI Input Joytick Keyboard Limits
ListBox Math Menu Mouse Music
Net Obsolete PC Pen Pic
Print RadioButton Rand RGB Sound
Sprite Str Stream Student Sys
Text Time TypeConv Video View
Window
)

constants = %w(
black blue brightblue brightcyan brightgreen
brightmagenta brightpurple brightred brightwhite brown
brushErrorBase cdMaxNumColors cdMaxNumColours cdMaxNumPages cdScreenHeight
cdScreenWidth clLanguageVersion clMaxNumDirStreams clMaxNumRunTimeArgs clMaxNumStreams
clRelease cmFPU cmOS cmProcessor colorbg
colourbg colorfg colourfg configErrorBase cyan
darkgray darkgrey defFontID defWinID dirErrorBase drawErrorBase
errWinID fileErrorBase fontDefaultID
fontErrorBase fsysErrorBase generalErrorBase gray green
grey guiErrorBase joystick1 joystick2 lexErrorBase
magenta mouseErrorBase musicErrorBase penErrorBase
placeCenterDisplay placeCentreWindow printerErrorBase purple
red rgbErrorBase spriteErrorBase streamErrorBase textErrorBase
timeErrorBase unixSignalToException viewErrorBase white windowErrorBase
yellow true false
)

reserved = %w(
addressint all asm
assert begin bind bits body
break by case
cheat checked class close collection
condition const decreasing def deferred
else elseif elsif end
endfor endif endloop exit
export external fcn
for fork forward free function
get handler if implement
inherit init
invariant label
loop module monitor
new
objectclass of opaque open
packed pause pervasive pointer post
pre priority proc procedure process
put quit read
record register result
return seek self set
signal skip tag
tell then timeout to
unchecked union unqualified
wait when write
)

import = %w(import include)

declarations = %w(
var enum type unit
)

types = %w(
boolean char string
real real4 real8
int int1 int2 int4
nat nat1 nat2 nat4
flexible array
)

operators = %w(
\+ - \* \/
< > = :
\^ #
~
& \|
\\( \\)
, \.
)

wordOperators = %w(
div mod rem
not and or xor
in
shl shr
)

state :root do
rule /[^\S\n]+/, Text
rule /\n/, Text

rule /#{operators.join('|')}/, Operator

rule %r(%.*?$), Comment::Single
rule %r(/\*.*?\*/)m, Comment::Multiline

rule /(?:#{constants.join('|')})\b/, Keyword::Constant
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see how this is done in other lexers, with a Set constructed separately, combined with a single rule and set lookups. This is done because Rouge matches each regex in turn, so reducing the number of regex matches is preferable so that a string can be excluded quickly. E.g. search for "rule id" in the C lexer.

rule /(?:#{declarations.join('|')})\b/, Keyword::Declaration
rule /(?:#{reserved.join('|')})\b/, Keyword::Reserved
rule /(?:#{types.join('|')})\b/, Keyword::Type

rule /(?:#{import.join('|')}).*/, Name::Namespace

rule /(?:#{modules.join('|')})(?=\.)\b/, Name::Builtin
rule /(?:#{methods.join('|')})\b/, Name::Function


rule /"(\\\\|\\"|[^"])*"/, Literal::String
rule /'\\?.'/, Literal::String::Char
rule /(?:\d*\.)?\d+/, Literal::Number

rule /\b(#{wordOperators.join('|')})\b/, Operator::Word

rule /[a-zA-Z_][a-zA-Z0-9_]*/, Name

end
end
end
end
14 changes: 14 additions & 0 deletions spec/lexers/turing_spec.rb
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*- #

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add '# frozen_string_literal: true'

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

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.t'
assert_guess :filename => 'foo.tu'
end
end
end
81 changes: 81 additions & 0 deletions spec/visual/samples/turing
@@ -0,0 +1,81 @@
% Class for the Player object.
unit
class Player
export getName, getScore, getCorrect, getWrong, createPlayer, addWrong, addCorrect, setConnection, getConnect

% Declare player record.
type player :
record
userName : string
port : int
score : real
correct : int
wrong : int
connect : int
address : string
end record

var me : player %Allow the class to refer to itself.

% Assign the values for the new player.
proc createPlayer (name : string, connectPort : int)
me.userName := name
me.port := connectPort
me.score := 0
me.correct := 0
me.wrong := 0
end createPlayer

% Return the player name.
fcn getName : string
result me.userName
end getName

% Return the player score.
fcn getScore : real
result me.score
end getScore

% Return how many answers this player has gotten correct.
fcn getCorrect : int
result me.correct
end getCorrect

% Return how many answers this player has gotten wrong.
fcn getWrong : int
result me.wrong
end getWrong

% Calculate the player score as a percentage.
proc calcScore
if (me.correct <= 0) then
me.score := 0
else
me.score := (me.correct / (me.correct + me.wrong)) * 100
end if
end calcScore

% Add one to the player's wrong count, and recalculate the score.
proc addWrong
me.wrong += 1
calcScore
end addWrong

% Add one the player's correct count, and recalculate the score.
proc addCorrect
me.correct += 1
calcScore
end addCorrect

% Set the IP and connection number for the player.
proc setConnection (c : int, ip : string)
me.connect := c
me.address := ip
end setConnection

% Return the connection number of the player.
fcn getConnect : int
result me.connect
end getConnect

end Player