Skip to content

Commit

Permalink
Add ISBL lexer (#891)
Browse files Browse the repository at this point in the history
This commit adds a lexer for ISBL.
  • Loading branch information
MedvedTMN committed Apr 3, 2020
1 parent c4bd736 commit f3fb856
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/rouge/demos/isbl
@@ -0,0 +1,4 @@
NameReq = Object.Requisites(SYSREQ_NAME)
if Assigned(NameReq.AsString)
ShowMessage("Привет мир")
endif
97 changes: 97 additions & 0 deletions lib/rouge/lexers/isbl.rb
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

module Rouge
module Lexers
class ISBL < RegexLexer
title "ISBL"
desc "The ISBL programming language"
tag 'isbl'
filenames '*.isbl'

def self.builtins
load File.join(__dir__, 'isbl/builtins.rb')
self.builtins
end

def self.constants
@constants ||= self.builtins["const"].merge(self.builtins["enum"]).collect!(&:downcase)
end

def self.interfaces
@interfaces ||= self.builtins["interface"].collect!(&:downcase)
end

def self.globals
@globals ||= self.builtins["global"].collect!(&:downcase)
end

def self.keywords
@keywords = Set.new %w(
and и else иначе endexcept endfinally endforeach конецвсе endif конецесли endwhile
конецпока except exitfor finally foreach все if если in в not не or или try while пока
)
end

state :whitespace do
rule %r/\s+/m, Text
rule %r(//.*?$), Comment::Single
rule %r(/[*].*?[*]/)m, Comment::Multiline
end

state :dotted do
mixin :whitespace
rule %r/[a-zа-яё_0-9]*/i do |m|
name = m[0]
if self.class.constants.include? name.downcase
token Name::Builtin
elsif in_state? :type
token Keyword::Type
else
token Name
end
pop!
end
end

state :type do
mixin :whitespace
rule %r/[a-zа-яё_0-9]*/i do |m|
name = m[0]
if self.class.interfaces.include? name.downcase
token Keyword::Type
else
token Name
end
pop!
end
rule %r/[.]/, Punctuation, :dotted
rule(//) { pop! }
end

state :root do
mixin :whitespace
rule %r/[:]/, Punctuation, :type
rule %r/[.]/, Punctuation, :dotted
rule %r/[\[\]();]/, Punctuation
rule %r([&*+=<>/-]), Operator
rule %r/\b[a-zа-яё_][a-zа-яё_0-9]*(?=[(])/i, Name::Function
rule %r/[a-zа-яё_!][a-zа-яё_0-9]*/i do |m|
name = m[0]
if self.class.keywords.include? name.downcase
token Keyword
elsif self.class.constants.include? name.downcase
token Name::Builtin
elsif self.class.globals.include? name.downcase
token Name::Variable::Global
else
token Name::Variable
end
end
rule %r/\b(\d+(\.\d+)?)\b/, Literal::Number
rule %r(["].*?["])m, Literal::String::Double
rule %r(['].*?['])m, Literal::String::Single
end
end
end
end
17 changes: 17 additions & 0 deletions lib/rouge/lexers/isbl/builtins.rb

Large diffs are not rendered by default.

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

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

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.isbl'
end
end
end
69 changes: 69 additions & 0 deletions spec/visual/samples/isbl
@@ -0,0 +1,69 @@
// Types
App : IApplication
Employees : IReference.РАБ = References.ReferenceFactory("РАБ").GetComponent

// Operators
Result = 1 + 1 / 2

// Numbers
Integer = 5
Float = 5.5
WordBool = True

// Strings
Double_Quotes = "An example"
Single_Quotes = 'An example'

// Comments

/********************************************
* Получить список кодов или ИД работников, *
* соответствующих пользователю. *
********************************************/

// Example code

ADD_EQUAL_NUMBER_TEMPLATE = "%s.%s = %s"
ADD_EQUAL_STATE_TEMPLATE = "%s.%s = '%s'"
EMPLOYEES_REFERENCE = "РАБ"
// Проверить, сущуствует ли пользователь с ИД UserID
ExceptionsOff()
FreeException()
ServiceFactory.GetUserByID(UserID)
ExceptionsOn()
if ExceptionExists()
Raise(CreateException("EDIRInvalidTypeOfParam";
LoadStringFmt("DIR21A2F148_1B41_40F3_9152_6E09E712025A"; "COMMON";
ArrayOf(UserID)); ecException)) // Не существует пользователя с ИД = %s
endif
Employees : IReference.РАБ = CreateReference(EMPLOYEES_REFERENCE; ArrayOf("Пользователь"; SYSREQ_STATE); FALSE)
Employees.Events.DisableAll
EmployeesTableName = Employees.TableName
EmployeesUserWhereID = Employees.AddWhere(Format(ADD_EQUAL_NUMBER_TEMPLATE; ArrayOf(EmployeesTableName;
Employees.Requisites("Пользователь").SQLFieldName; UserID)))
if OnlyActive
EmployeesStateWhereID = Employees.AddWhere(Format(ADD_EQUAL_STATE_TEMPLATE; ArrayOf(EmployeesTableName;
Employees.Requisites(SYSREQ_STATE).SQLFieldName; Employees.Requisites(SYSREQ_STATE).Items.IDByValue("Действующая"))))
endif
if Assigned(OurOrgID)
EmployeesOurOrgIDWhereID = Employees.AddWhere(Format(ADD_EQUAL_STATE_TEMPLATE; ArrayOf(EmployeesTableName;
Employees.Requisites("НашаОрг").SQLFieldName; OurOrgID)))
endif
Employees.Open()
Result = CreateStringList()
foreach Employee in Employees
if IsResultCode
Result.Add(Employee.SYSREQ_CODE)
else
Result.Add(Employee.SYSREQ_ID)
endif
endforeach
Employees.Close()
Employees.DelWhere(EmployeesUserWhereID)
if OnlyActive
Employees.DelWhere(EmployeesStateWhereID)
endif
if Assigned(OurOrgID)
Employees.DelWhere(EmployeesOurOrgIDWhereID)
endif
Employees.Events.EnableAll

0 comments on commit f3fb856

Please sign in to comment.