rouge-picat 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/LICENSE +9 -0
- data/README.md +69 -0
- data/lib/rouge-picat.rb +154 -0
- data/rouge-picat.gemspec +19 -0
- metadata +65 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4bf3b0a384725113f58d6e2f389414168405f241261964102744e41758a71942
|
|
4
|
+
data.tar.gz: 39e997b9b5d4d16a29f063f659830c438c489a0b01e8242f0ae574a15d1fc374
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a63a045b27fbe55b9c8d5323f08bd8c41e9a3ae60d3b38973b1284af2168d43d5c4c671b7fd0dae2878c880603e54ba7166c52985655f98d0f158bdb1b118907
|
|
7
|
+
data.tar.gz: 794ef72e1d23cc3b6ce7318569e7044cb315ab950e1a4d8a007399da919d9ca73dd36469911cc69306956806c0cd9cc197e3f29182ccf6ee57bea0a50bd4f532
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arclight Automata
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# rouge-picat
|
|
2
|
+
|
|
3
|
+
A [Rouge](https://github.com/rouge-ruby/rouge) plugin that adds syntax
|
|
4
|
+
highlighting support for the [Picat](http://picat-lang.org/) programming
|
|
5
|
+
language.
|
|
6
|
+
|
|
7
|
+
Picat is a logic-based multi-paradigm programming language aimed at
|
|
8
|
+
general-purpose applications, combining features from logic programming,
|
|
9
|
+
functional programming, and scripting languages.
|
|
10
|
+
|
|
11
|
+
## Background
|
|
12
|
+
|
|
13
|
+
This lexer was originally submitted to Rouge core as
|
|
14
|
+
[rouge-ruby/rouge#2110](https://github.com/rouge-ruby/rouge/pull/2110).
|
|
15
|
+
The Rouge maintainers declined the PR and asked that new languages be
|
|
16
|
+
distributed as plugin gems instead — this repository is that plugin.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Add this line to your application's Gemfile:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
gem 'rouge-picat'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or install it directly:
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
$ gem install rouge-picat
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
Require the gem after Rouge and the lexer registers itself under the
|
|
35
|
+
`picat` tag:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
require 'rouge'
|
|
39
|
+
require 'rouge-picat'
|
|
40
|
+
|
|
41
|
+
source = File.read('queens.pi')
|
|
42
|
+
formatter = Rouge::Formatters::HTML.new
|
|
43
|
+
lexer = Rouge::Lexer.find('picat')
|
|
44
|
+
|
|
45
|
+
formatter.format(lexer.lex(source))
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The lexer is also picked up automatically when guessing by filename
|
|
49
|
+
(`*.pi`) or mimetype (`text/x-picat`).
|
|
50
|
+
|
|
51
|
+
## Development
|
|
52
|
+
|
|
53
|
+
* `spec/sample.pi` holds the visual spec - this is text intended to
|
|
54
|
+
stress-test the lexer and catch any weirdnesses or errors.
|
|
55
|
+
* `ruby preview.rb` will output the highlighted sample to the terminal.
|
|
56
|
+
Set the environment variable `DEBUG=1` to instead output detailed debugging
|
|
57
|
+
information.
|
|
58
|
+
* `rake` or `rake spec` runs the tests.
|
|
59
|
+
* `rake server` runs a preview server on port 9292, which hot-reloads the lexer.
|
|
60
|
+
|
|
61
|
+
This plugin follows the structure of the
|
|
62
|
+
[rouge-plugin-example](https://github.com/rouge-ruby/rouge-plugin-example)
|
|
63
|
+
repository. See also Rouge's [Lexer Development Guide][lexer-dev-doc].
|
|
64
|
+
|
|
65
|
+
[lexer-dev-doc]: https://rouge-ruby.github.io/docs/file.LexerDevelopment.html "Rouge's lexer development guide"
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT - see [LICENSE](LICENSE).
|
data/lib/rouge-picat.rb
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*- #
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'rouge' unless defined?(Rouge)
|
|
5
|
+
|
|
6
|
+
module RougePicat
|
|
7
|
+
class Picat < Rouge::RegexLexer
|
|
8
|
+
title "Picat"
|
|
9
|
+
desc "The Picat programming language (picat-lang.org)"
|
|
10
|
+
|
|
11
|
+
tag 'picat'
|
|
12
|
+
filenames '*.pi'
|
|
13
|
+
mimetypes 'text/x-picat'
|
|
14
|
+
|
|
15
|
+
demo <<~'DEMO'
|
|
16
|
+
module main.
|
|
17
|
+
|
|
18
|
+
import util.
|
|
19
|
+
|
|
20
|
+
% Calculate factorial using recursion
|
|
21
|
+
fact(0) = 1.
|
|
22
|
+
fact(N) = N * fact(N-1) => N > 0.
|
|
23
|
+
|
|
24
|
+
main =>
|
|
25
|
+
X = 5,
|
|
26
|
+
writef("Factorial of %d is %d\n", X, fact(X)),
|
|
27
|
+
Sum = sum([1,2,3]),
|
|
28
|
+
writef("Sum = %d\n", Sum).
|
|
29
|
+
DEMO
|
|
30
|
+
|
|
31
|
+
def self.keywords
|
|
32
|
+
@keywords ||= Set.new %w(
|
|
33
|
+
module import private table index
|
|
34
|
+
if else elseif end foreach while do
|
|
35
|
+
not fail true false
|
|
36
|
+
catch try in
|
|
37
|
+
repeat once var throw
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.builtins
|
|
42
|
+
@builtins ||= Set.new %w(
|
|
43
|
+
append write writeln print println member length
|
|
44
|
+
solve solve_all new_array new_map new_set
|
|
45
|
+
min max sum prod floor ceiling round
|
|
46
|
+
abs sqrt sin cos tan log exp
|
|
47
|
+
open close printf get_heap_map get_global_map
|
|
48
|
+
get_table_map instance final action solve
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
state :root do
|
|
53
|
+
rule %r/\s+/m, Text
|
|
54
|
+
rule %r/%.*$/, Comment::Single
|
|
55
|
+
rule %r/\/\*/, Comment::Multiline, :multiline_comment
|
|
56
|
+
|
|
57
|
+
# Module declaration
|
|
58
|
+
rule %r/(module)(\s+)([a-z][a-zA-Z0-9_]*)/m do
|
|
59
|
+
groups Keyword::Namespace, Text::Whitespace, Name::Namespace
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Import declaration
|
|
63
|
+
rule %r/(import)(\s+)([a-z][a-zA-Z0-9_]*)/m do
|
|
64
|
+
groups Keyword::Namespace, Text::Whitespace, Name::Namespace
|
|
65
|
+
push :import_list
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Handle bare 'import' without immediate module name
|
|
69
|
+
rule %r/(import)(\s*$)/ do
|
|
70
|
+
groups Keyword::Namespace, Text::Whitespace
|
|
71
|
+
push :import_list
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Numbers with underscore separators (must come before regular integers)
|
|
75
|
+
rule %r/\d+(_\d+)+/, Num::Integer
|
|
76
|
+
|
|
77
|
+
# Other numbers
|
|
78
|
+
rule %r/0[xX][0-9a-fA-F]+/, Num::Hex
|
|
79
|
+
rule %r/0[oO][0-7]+/, Num::Oct
|
|
80
|
+
rule %r/0[bB][01]+/, Num::Bin
|
|
81
|
+
rule %r/[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?/, Num::Float
|
|
82
|
+
rule %r/[0-9]+/, Num::Integer
|
|
83
|
+
|
|
84
|
+
# Strings and Atoms
|
|
85
|
+
rule %r/"(\\.|[^"])*"/, Str::Double
|
|
86
|
+
rule %r/'(\\.|[^'])*'/, Str::Symbol # Quoted atoms
|
|
87
|
+
|
|
88
|
+
# Variables
|
|
89
|
+
rule %r/[A-Z_][A-Za-z0-9_]*/, Name::Variable
|
|
90
|
+
|
|
91
|
+
# Keywords and builtins (moved before other identifier patterns)
|
|
92
|
+
rule %r/[a-z][a-zA-Z0-9_]*(?=[^a-zA-Z0-9_])/ do |m|
|
|
93
|
+
if self.class.keywords.include? m[0]
|
|
94
|
+
token Keyword
|
|
95
|
+
elsif self.class.builtins.include? m[0]
|
|
96
|
+
token Name::Builtin
|
|
97
|
+
else
|
|
98
|
+
token Name
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Module-qualified names
|
|
103
|
+
rule %r/([a-z][a-zA-Z0-9_]*)(\.)([a-z][a-zA-Z0-9_]*)/ do
|
|
104
|
+
groups Name::Namespace, Punctuation, Name::Function
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Structure notation
|
|
108
|
+
rule %r/\$[a-z][a-zA-Z0-9_]*/, Name::Class
|
|
109
|
+
|
|
110
|
+
# Other identifiers
|
|
111
|
+
rule %r/[a-z][a-zA-Z0-9_]*/, Name
|
|
112
|
+
|
|
113
|
+
# Import items (commas and periods)
|
|
114
|
+
rule %r/,|\./, Punctuation
|
|
115
|
+
|
|
116
|
+
# Constraint operators
|
|
117
|
+
rule %r/#=>|#<=>|#\/\\|#\\\/|#\^|#~|#=|#!=|#<|#=<|#<=|#>|#>=/, Operator
|
|
118
|
+
|
|
119
|
+
# Term comparison operators
|
|
120
|
+
rule %r/@<|@=<|@<=|@>|@>=/, Operator
|
|
121
|
+
|
|
122
|
+
# DCG notation
|
|
123
|
+
rule %r/-->/, Operator
|
|
124
|
+
|
|
125
|
+
# List comprehension separator
|
|
126
|
+
rule %r/\s+:\s+/, Punctuation
|
|
127
|
+
|
|
128
|
+
# Range notation
|
|
129
|
+
rule %r/\.\./, Operator
|
|
130
|
+
|
|
131
|
+
# List cons operator (|)
|
|
132
|
+
rule %r/\|/, Punctuation
|
|
133
|
+
|
|
134
|
+
# Other operators and punctuation
|
|
135
|
+
rule %r/=>|:=|\?=>|==|!=|=<|>=|::|\+\+|--|!|;|:|\.|=|<|>|\+|-|\*|\/|\[|\]|\{|\}|\(|\)|\$|@/, Operator
|
|
136
|
+
|
|
137
|
+
# Table/index declarations
|
|
138
|
+
rule %r/(\+|-)(?=[\s,\)])/, Operator
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
state :multiline_comment do
|
|
142
|
+
rule %r/[^*\/]+/m, Comment::Multiline
|
|
143
|
+
rule %r/\*\//, Comment::Multiline, :pop!
|
|
144
|
+
rule %r/[\*\/]/, Comment::Multiline
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
state :import_list do
|
|
148
|
+
rule %r/\s+/m, Text::Whitespace
|
|
149
|
+
rule %r/[a-z][a-zA-Z0-9_]*/, Name::Namespace
|
|
150
|
+
rule %r/,/, Punctuation
|
|
151
|
+
rule %r/\./, Punctuation, :pop!
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
data/rouge-picat.gemspec
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = "rouge-picat"
|
|
5
|
+
s.version = "0.1.0"
|
|
6
|
+
s.authors = ["Arclight Automata"]
|
|
7
|
+
s.email = ["root@arclight.run"]
|
|
8
|
+
s.summary = "A Picat language plugin for Rouge"
|
|
9
|
+
s.description = <<-desc.strip.gsub(/\s+/, ' ')
|
|
10
|
+
Support for the Picat programming language (picat-lang.org) for Rouge
|
|
11
|
+
desc
|
|
12
|
+
|
|
13
|
+
s.homepage = "https://github.com/arclight-automata/rouge-picat"
|
|
14
|
+
s.files = Dir['Gemfile', 'LICENSE', 'README.md', 'rouge-picat.gemspec', 'lib/**/*.rb']
|
|
15
|
+
s.licenses = ['MIT']
|
|
16
|
+
s.required_ruby_version = '>= 3.0'
|
|
17
|
+
|
|
18
|
+
s.add_dependency 'rouge', '>= 4.0', '< 6'
|
|
19
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rouge-picat
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Arclight Automata
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-08-05 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rouge
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '4.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '6'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '4.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '6'
|
|
32
|
+
description: Support for the Picat programming language (picat-lang.org) for Rouge
|
|
33
|
+
email:
|
|
34
|
+
- root@arclight.run
|
|
35
|
+
executables: []
|
|
36
|
+
extensions: []
|
|
37
|
+
extra_rdoc_files: []
|
|
38
|
+
files:
|
|
39
|
+
- Gemfile
|
|
40
|
+
- LICENSE
|
|
41
|
+
- README.md
|
|
42
|
+
- lib/rouge-picat.rb
|
|
43
|
+
- rouge-picat.gemspec
|
|
44
|
+
homepage: https://github.com/arclight-automata/rouge-picat
|
|
45
|
+
licenses:
|
|
46
|
+
- MIT
|
|
47
|
+
metadata: {}
|
|
48
|
+
rdoc_options: []
|
|
49
|
+
require_paths:
|
|
50
|
+
- lib
|
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '3.0'
|
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
requirements: []
|
|
62
|
+
rubygems_version: 3.6.2
|
|
63
|
+
specification_version: 4
|
|
64
|
+
summary: A Picat language plugin for Rouge
|
|
65
|
+
test_files: []
|