From 02a05ed4f9134b3eacd6acd4dfbd61fd4d9688c8 Mon Sep 17 00:00:00 2001 From: Peter Hull Date: Wed, 19 May 2021 14:58:32 +0100 Subject: [PATCH 1/2] Initial check-in of Dylan language --- lib/rouge/demos/dylan | 8 +++++ lib/rouge/lexers/dylan.rb | 69 +++++++++++++++++++++++++++++++++++++++ spec/visual/samples/dylan | 51 +++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 lib/rouge/demos/dylan create mode 100644 lib/rouge/lexers/dylan.rb create mode 100644 spec/visual/samples/dylan diff --git a/lib/rouge/demos/dylan b/lib/rouge/demos/dylan new file mode 100644 index 0000000000..06fb771c4d --- /dev/null +++ b/lib/rouge/demos/dylan @@ -0,0 +1,8 @@ +// Various keywords and constants +define method demo(x :: , #key y = "demo") => () + let z = #xFEE8 + #o277; + let w = '\n'; + format-out("%d %s %d %c", x + 100, y, z, w); +end method; + +demo(99, y: "hello"); \ No newline at end of file diff --git a/lib/rouge/lexers/dylan.rb b/lib/rouge/lexers/dylan.rb new file mode 100644 index 0000000000..01a604a55e --- /dev/null +++ b/lib/rouge/lexers/dylan.rb @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- # +# frozen_string_literal: true + +module Rouge + module Lexers + class Dylan < RegexLexer + title 'Dylan' + desc 'Dylan Language' + tag 'dylan' + filenames '*.dylan' + # Definitions from the Dylan Reference Manual + core_word=%w(define end handler let local macro otherwise) + begin_word=%w(begin block case for if method) + function_word=[] + define_body_word=%w(class library method module) + define_list_word=%w(constant variable domain) + reserved_word=core_word+begin_word+function_word+define_body_word+define_list_word + punctuation=%w'( ) , . ; [ ] { } :: - = == => #( #[ ## ? ?? ?= ... ' + hash_word=%w(#t #f #next #rest #key #all-keys #include) + graphic_character=%w(! & * < > | ^ $ % @ _) + special_character=%w(- + ~ ? / =) + binary_operator=%w(+ - * / ^ = == ~= ~== < <= > >= & | :=) + unary_operator=%w(- ~) + binary_integer=%r(#b[01]+) + octal_integer=%r(#o[0-7]+) + decimal_integer=%r([+-]?[0-9]+) + hex_integer=%r(#x[0-9a-f]+)i + ratio=%r([+-]?[0-9]+/[0-9]+) + floating_point=%r([+-]?([0-9]*\.[0-9]+(E[+-]?[0-9]+)?|[0-9]+\.[0-9]*(E[+-]?[0-9]+)?|[0-9]+E[+-]?[0-9]+))i + word_character=/[a-z0-9#{Regexp.escape((graphic_character+special_character).join(''))}]/i + initial_word_character=/[\\a-z0-9#{Regexp.escape(graphic_character.join(''))}]/i + word=%r(#{initial_word_character}#{word_character}*)i + punc = Regexp.new(punctuation.map {|s| Regexp.escape(s)}.join("|")) + oper = Regexp.new((binary_operator+unary_operator).map {|s| Regexp.escape(s)}.join("|")) + # Words in < > brackets are class names but only by convention + def angle?(matched) + /^<.+>$/ =~ matched[0] + end + state :root do + # Comments + rule %r(//.*?$), Comment::Single + rule %r(/\*.*?\*/)m, Comment::Multiline + # Keywords + rule %r/(#{reserved_word.join('|')})\b/, Keyword + rule %r/(#{hash_word.join('|')})\b/, Keyword::Constant + # Numbers + rule ratio, Literal::Number::Other + rule floating_point, Literal::Number::Float + rule binary_integer, Literal::Number::Bin + rule octal_integer, Literal::Number::Oct + rule decimal_integer, Literal::Number::Integer + rule hex_integer, Literal::Number::Hex + # Names + rule %r/[-\w\d\.]+:/, Name::Tag + rule word do |w| + token angle?(w) ? Name::Class : Name + end + # Operators and punctuation + rule punc, Operator + rule oper, Operator + rule %r/:/, Operator # For 'constrained names' + # Strings, characters and whitespace + rule %r/"(\\\\|\\"|[^"])*"/, Str + rule %r/'([^\\']|(\\[\\'abefnrt0])|(\\[0-9a-f]+))'/, Str::Char + rule %r/\s+/, Text::Whitespace + end + end + end +end diff --git a/spec/visual/samples/dylan b/spec/visual/samples/dylan new file mode 100644 index 0000000000..2ba41b416d --- /dev/null +++ b/spec/visual/samples/dylan @@ -0,0 +1,51 @@ +Module: Factorial +Synopsis: Factorial "application." +Author: Steve Rowley +Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. + All rights reserved. +License: See License.txt in this distribution for details. +Warranty: Distributed WITHOUT WARRANTY OF ANY KIND + +/// +/// The canonical recursive function. +/// + +define function factorial (n :: ) => (n! :: ) + case + n < 0 => error("Can't take factorial of negative integer: %d\n", n); + n = 0 => 1; + otherwise => n * factorial(n - 1); + end +end; + +define function factorial-top-level () => () + let arguments = application-arguments(); + if (arguments.size == 0) + format-out("Usage: %s number ...\n", application-name()); + else + format-out("$maximum-integer = %d\n", $maximum-integer); + format-out("$minimum-integer = %d\n", $minimum-integer); + for (i from 0 below size(arguments)) + let arg = arguments[i]; + block (loop-continue) + let n = block () + string-to-integer(arg); + exception () + format-out("Skipping invalid argument %=.\n", arg); + loop-continue(); + end block; + let n! = 0; + profiling (cpu-time-seconds, cpu-time-microseconds) + n! := factorial(n) + results + format-out("factorial(%d) = %d (in %d.%s seconds)\n", n, n!, + cpu-time-seconds, integer-to-string(cpu-time-microseconds, size: 6)); + end profiling; + exception (e :: ) + format-out("factorial(%s) - Error: %s\n", arg, e); + end block; + end for; + end if; +end function factorial-top-level; + +factorial-top-level(); From 65339a01de2f9923f2e42fdd614439ff1c265db0 Mon Sep 17 00:00:00 2001 From: Peter Hull Date: Fri, 16 Dec 2022 22:14:17 +0000 Subject: [PATCH 2/2] Add newline to end to fix linter error --- lib/rouge/demos/dylan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rouge/demos/dylan b/lib/rouge/demos/dylan index 06fb771c4d..9e4aef2dfa 100644 --- a/lib/rouge/demos/dylan +++ b/lib/rouge/demos/dylan @@ -5,4 +5,4 @@ define method demo(x :: , #key y = "demo") => () format-out("%d %s %d %c", x + 100, y, z, w); end method; -demo(99, y: "hello"); \ No newline at end of file +demo(99, y: "hello");