-
Notifications
You must be signed in to change notification settings - Fork 750
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
348 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,13 @@ | ||
module main. | ||
|
||
import util. | ||
|
||
% Calculate factorial using recursion | ||
fact(0) = 1. | ||
fact(N) = N * fact(N-1) => N > 0. | ||
|
||
main => | ||
X = 5, | ||
writef("Factorial of %d is %d\n", X, fact(X)), | ||
Sum = sum([1,2,3]), | ||
writef("Sum = %d\n", Sum). |
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,138 @@ | ||
# -*- coding: utf-8 -*- # | ||
# frozen_string_literal: true | ||
|
||
module Rouge | ||
module Lexers | ||
class Picat < RegexLexer | ||
title "Picat" | ||
desc "The Picat programming language (picat-lang.org)" | ||
|
||
tag 'picat' | ||
filenames '*.pi' | ||
mimetypes 'text/x-picat' | ||
|
||
def self.keywords | ||
@keywords ||= Set.new %w( | ||
module import private table index | ||
if else elseif end foreach while do | ||
not fail true false | ||
catch try in | ||
repeat once var throw | ||
) | ||
end | ||
|
||
def self.builtins | ||
@builtins ||= Set.new %w( | ||
append write writeln print println member length | ||
solve solve_all new_array new_map new_set | ||
min max sum prod floor ceiling round | ||
abs sqrt sin cos tan log exp | ||
open close printf get_heap_map get_global_map | ||
get_table_map instance final action solve | ||
) | ||
end | ||
|
||
state :root do | ||
rule %r/\s+/m, Text | ||
rule %r/%.*$/, Comment::Single | ||
rule %r/\/\*/, Comment::Multiline, :multiline_comment | ||
|
||
# Module declaration | ||
rule %r/(module)(\s+)([a-z][a-zA-Z0-9_]*)/m do | ||
groups Keyword::Namespace, Text::Whitespace, Name::Namespace | ||
end | ||
|
||
# Import declaration | ||
rule %r/(import)(\s+)([a-z][a-zA-Z0-9_]*)/m do | ||
groups Keyword::Namespace, Text::Whitespace, Name::Namespace | ||
push :import_list | ||
end | ||
|
||
# Handle bare 'import' without immediate module name | ||
rule %r/(import)(\s*$)/ do | ||
groups Keyword::Namespace, Text::Whitespace | ||
push :import_list | ||
end | ||
|
||
# Numbers with underscore separators (must come before regular integers) | ||
rule %r/\d+(_\d+)+/, Num::Integer | ||
|
||
# Other numbers | ||
rule %r/0[xX][0-9a-fA-F]+/, Num::Hex | ||
rule %r/0[oO][0-7]+/, Num::Oct | ||
rule %r/0[bB][01]+/, Num::Bin | ||
rule %r/[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?/, Num::Float | ||
rule %r/[0-9]+/, Num::Integer | ||
|
||
# Strings and Atoms | ||
rule %r/"(\\.|[^"])*"/, Str::Double | ||
rule %r/'(\\.|[^'])*'/, Str::Symbol # Quoted atoms | ||
|
||
# Variables | ||
rule %r/[A-Z_][A-Za-z0-9_]*/, Name::Variable | ||
|
||
# Keywords and builtins (moved before other identifier patterns) | ||
rule %r/[a-z][a-zA-Z0-9_]*(?=[^a-zA-Z0-9_])/ do |m| | ||
if self.class.keywords.include? m[0] | ||
token Keyword | ||
elsif self.class.builtins.include? m[0] | ||
token Name::Builtin | ||
else | ||
token Name | ||
end | ||
end | ||
|
||
# Module-qualified names | ||
rule %r/([a-z][a-zA-Z0-9_]*)(\.)([a-z][a-zA-Z0-9_]*)/ do | ||
groups Name::Namespace, Punctuation, Name::Function | ||
end | ||
|
||
# Structure notation | ||
rule %r/\$[a-z][a-zA-Z0-9_]*/, Name::Class | ||
|
||
# Other identifiers | ||
rule %r/[a-z][a-zA-Z0-9_]*/, Name | ||
|
||
# Import items (commas and periods) | ||
rule %r/,|\./, Punctuation | ||
|
||
# Constraint operators | ||
rule %r/#=>|#<=>|#\/\\|#\\\/|#\^|#~|#=|#!=|#<|#=<|#<=|#>|#>=/, Operator | ||
|
||
# Term comparison operators | ||
rule %r/@<|@=<|@<=|@>|@>=/, Operator | ||
|
||
# DCG notation | ||
rule %r/-->/, Operator | ||
|
||
# List comprehension separator | ||
rule %r/\s+:\s+/, Punctuation | ||
|
||
# Range notation | ||
rule %r/\.\./, Operator | ||
|
||
# List cons operator (|) | ||
rule %r/\|/, Punctuation | ||
|
||
# Other operators and punctuation | ||
rule %r/=>|:=|\?=>|==|!=|=<|>=|::|\+\+|--|!|;|:|\.|=|<|>|\+|-|\*|\/|\[|\]|\{|\}|\(|\)|\$|@/, Operator | ||
|
||
# Table/index declarations | ||
rule %r/(\+|-)(?=[\s,\)])/, Operator | ||
end | ||
|
||
state :multiline_comment do | ||
rule %r/[^*\/]+/m, Comment::Multiline | ||
rule %r/\*\//, Comment::Multiline, :pop! | ||
rule %r/[\*\/]/, Comment::Multiline | ||
end | ||
|
||
state :import_list do | ||
rule %r/\s+/m, Text::Whitespace | ||
rule %r/[a-z][a-zA-Z0-9_]*/, Name::Namespace | ||
rule %r/,/, Punctuation | ||
rule %r/\./, Punctuation, :pop! | ||
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,18 @@ | ||
# -*- coding: utf-8 -*- # | ||
# frozen_string_literal: true | ||
|
||
describe Rouge::Lexers::Picat do | ||
let(:subject) { Rouge::Lexers::Picat.new } | ||
|
||
describe 'guessing' do | ||
include Support::Guessing | ||
|
||
it 'guesses by filename' do | ||
assert_guess :filename => 'foo.pi' | ||
end | ||
|
||
it 'guesses by mimetype' do | ||
assert_guess :mimetype => 'text/x-picat' | ||
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,179 @@ | ||
/* Picat Language Sample | ||
Demonstrating syntax highlighting features */ | ||
|
||
module example. | ||
|
||
import | ||
util, | ||
cp. | ||
|
||
% Different number formats | ||
Nums = [ | ||
1_000_000, % Underscore separator | ||
0xFFF, % Hexadecimal | ||
0o777, % Octal | ||
0b1010, % Binary | ||
1.23e-4, % Scientific notation | ||
3.14159 % Float | ||
]. | ||
|
||
% String escape sequences | ||
Strings = [ | ||
"Double \"quoted\" string", | ||
"Line 1\nLine 2", | ||
"Tab\tafter", | ||
"Unicode \u0041", | ||
'Single \'quoted\' atom' | ||
]. | ||
|
||
% Special characters in atoms | ||
atom_1, | ||
'atom-with-dashes', | ||
'atom with spaces', | ||
'atom@with@special@chars'. | ||
|
||
% Special operators | ||
X #=> Y, % Constraint implication | ||
X #<=> Y, % Constraint equivalence | ||
X #/\ Y, % Constraint AND | ||
X #\/ Y, % Constraint OR | ||
X #^ Y, % Constraint XOR | ||
#~ X, % Constraint NOT | ||
|
||
% Special comparison operators | ||
X @< Y, % Term comparison less than | ||
X @=< Y, % Term comparison less than or equal | ||
X @> Y, % Term comparison greater than | ||
X @>= Y, % Term comparison greater than or equal | ||
|
||
% Range notation | ||
List1 = 1..10, % Range with step 1 | ||
List2 = 1..2..10, % Range with step 2 | ||
|
||
% Special built-in predicates | ||
once(Goal), | ||
repeat, | ||
true, | ||
fail, | ||
|
||
% Assignment vs unification | ||
X = Y, % Unification | ||
X := Y, % Assignment | ||
X == Y, % Term equality | ||
X !== Y, % Term inequality | ||
X =:= Y, % Arithmetic equality | ||
|
||
% Special list/array access | ||
List = [1,2,3,4,5], | ||
First = List[1], | ||
Slice = List[2..4], | ||
Array = {1,2,3,4,5}, | ||
AFirst = Array[1], | ||
ASlice = Array[2..4]. | ||
|
||
% DCG notation (since version 3.0) | ||
sentence --> noun_phrase, verb_phrase. | ||
|
||
% Variables and lists | ||
process_list(List) => | ||
[Head|Tail] = List, | ||
foreach(X in Tail) | ||
if X > Head then | ||
println(X) | ||
elseif X < Head then | ||
println("Less") | ||
else | ||
println("Equal") | ||
end | ||
end. | ||
|
||
% Using built-in functions | ||
math_ops => | ||
A = abs(-42), | ||
B = sqrt(2), | ||
C = sin(3.14159), | ||
D = new_array(3), | ||
Map = new_map(), | ||
Set = new_set([1,2,3]). | ||
|
||
% Pattern matching and operators | ||
compare(X, Y) ?=> | ||
X >= Y, | ||
X =< 100, | ||
X != Y, | ||
X :: 1..10. | ||
compare(_, _) => fail. | ||
|
||
% Solving example | ||
solve_puzzle => | ||
Vars = [X,Y,Z], | ||
Vars :: 1..9, | ||
sum(Vars) #= 15, | ||
solve(Vars). | ||
|
||
% Functions with returns | ||
factorial(0) = 1. | ||
factorial(N) = F => F = N * factorial(N - 1). | ||
|
||
% List comprehensions | ||
S = [X*X : X in 1..20, X mod 2 = 0]. | ||
|
||
% Index on either first or second argument | ||
index (+,-) (-,+) | ||
edge(a,b). | ||
edge(a,c). | ||
edge(b,c). | ||
edge(c,b). | ||
|
||
% Private tabled function | ||
private | ||
table | ||
fibonacci(0) = 1. | ||
fibonacci(1) = 1. | ||
fibonacci(N) = F => F = fibonacci(N-1) + fibonacci(N-2). | ||
|
||
% Structures | ||
print_books => | ||
B1 = $book("Dune", "Frank Herbert"), | ||
println(B1[1]), % Access first element | ||
B2 = new_map([title = "Dune", author = "Frank Herbert"]), | ||
println(B2.get(title)). | ||
|
||
% Action rules for event-driven programming | ||
echo(X,Flag), var(Flag), {event(X,T)} => | ||
writeln(T). | ||
echo(_X,_Flag) => | ||
writeln(done). | ||
|
||
% Exception handling | ||
divide(A, B) => | ||
catch( | ||
(C = A / B), | ||
error(zero_divisor, _), | ||
println("Division by zero") | ||
). | ||
|
||
% Pattern matching with as-patterns (@) | ||
process(L@[H|T]) => | ||
println(L), % whole list | ||
println(H), % head | ||
println(T). % tail | ||
|
||
% Pattern matching with disjunction | ||
match_guard(X) ?=> | ||
X = 1; | ||
X = 2; | ||
X = 3. | ||
|
||
% Using the planner module | ||
import planner. | ||
final([n,n,n,n]) => true. % Example goal state | ||
action(S,NextS,Action,Cost) => ... % Define possible actions | ||
|
||
% Basic I/O | ||
write_data => | ||
FD = open("data.txt", write), | ||
foreach(I in 1..10) | ||
printf(FD, "%d\n", I) | ||
end, | ||
close(FD). |