diff --git a/src/myst/syntax/lexer.cr b/src/myst/syntax/lexer.cr index 62eead9..243182e 100644 --- a/src/myst/syntax/lexer.cr +++ b/src/myst/syntax/lexer.cr @@ -397,6 +397,11 @@ module Myst when "\\n" then '\n' when "\\\"" then '"' when "\\t" then '\t' + when "\\e" then '\e' + when "\\r" then '\r' + when "\\f" then '\f' + when "\\v" then '\v' + when "\\b" then '\b' when "\\0" then '\0' end end diff --git a/stdlib/colored.mt b/stdlib/colored.mt new file mode 100644 index 0000000..581a1ec --- /dev/null +++ b/stdlib/colored.mt @@ -0,0 +1,39 @@ +defmodule Color + def ansi_from_symbol(sym) + when sym == :black + return ANSI_BLACK + when sym == :red + return ANSI_RED + when sym == :green + return ANSI_GREEN + when sym == :yellow + return ANSI_YELLOW + when sym == :blue + return ANSI_BLUE + when sym == :purple + return ANSI_PURPLE + when sym == :cyan + return ANSI_CYAN + when sym == :white + return ANSI_WHITE + else + raise ":\"<(sym)>\" is not a valid color" + end + end + + ANSI_RESET = "\e[0m" + + ANSI_BLACK = "\e[0;30m" + ANSI_RED = "\e[0;31m" + ANSI_GREEN = "\e[0;32m" + ANSI_YELLOW = "\e[0;33m" + ANSI_BLUE = "\e[0;34m" + ANSI_PURPLE = "\e[0;35m" + ANSI_CYAN = "\e[0;36m" + ANSI_WHITE = "\e[0;37m" + + def colored(string, sym : Symbol) + color = ansi_from_symbol(sym) + "<(color)><(string)><(ANSI_RESET)>" + end +end diff --git a/stdlib/list.mt b/stdlib/list.mt index ac0c4b0..4f9a605 100644 --- a/stdlib/list.mt +++ b/stdlib/list.mt @@ -9,6 +9,26 @@ deftype List "[" + join(",") + "]" end + def first + self[0] + end + + def first? + first + rescue + nil + end + + def last + self[self.size - 1] + end + + def last? + last + rescue + nil + end + # empty? -> bool # # Return `true` if the List contains 0 elements. Return `false` otherwise. diff --git a/stdlib/spec.mt b/stdlib/spec.mt index 32fb2fc..b808a71 100644 --- a/stdlib/spec.mt +++ b/stdlib/spec.mt @@ -1,6 +1,10 @@ require "./spec/dsl.mt" require "./spec/errors.mt" require "./spec/single_spec.mt" +require "./spec/describe_container.mt" +require "./colored.mt" + +include Spec # Spec # @@ -24,6 +28,9 @@ require "./spec/single_spec.mt" # Calls). This should be addressed before too long, since it's a fairly common # use case, but a basic Spec library does not require it. defmodule Spec + describe_stack = [] + include DSL + def it(name, &block) spec = %SingleSpec{name} spec.run{ block() } @@ -39,6 +46,8 @@ defmodule Spec def describe(name, &block) + describe_stack.push(%DescribeContainer{name}) block() + describe_stack.pop end end diff --git a/stdlib/spec/describe_container.mt b/stdlib/spec/describe_container.mt new file mode 100644 index 0000000..e2a708a --- /dev/null +++ b/stdlib/spec/describe_container.mt @@ -0,0 +1,17 @@ +defmodule Spec + deftype DescribeContainer + def initialize(name : String) + @name = name + end + + def name; @name; end + + def get_path(current : String, stack_index) + when !describe_stack.empty? && next_describe = describe_stack[stack_index] + return describe_stack[stack_index].get_path("<(@name)> <(current)>", stack_index - 1) + else + "<(@name)> <(current)>" + end + end + end +end diff --git a/stdlib/spec/single_spec.mt b/stdlib/spec/single_spec.mt index 0708084..6de5e31 100644 --- a/stdlib/spec/single_spec.mt +++ b/stdlib/spec/single_spec.mt @@ -9,9 +9,20 @@ defmodule Spec def run(&block) block() - STDOUT.print(".") + STDOUT.print(Color.colored(".", :green)) rescue failure - STDOUT.puts(failure) + STDOUT.puts("\n") + + last = describe_stack.last? + + when last + STDOUT.puts(Color.colored(" <(last.get_path(@name, describe_stack.size -1))>", :red)) + else + STDOUT.puts(Color.colored(" <(@name)>"), :red) + end + + STDOUT.puts(Color.colored(" <(failure)>", :red)) + STDOUT.puts exit(1) end end