This commit is contained in:
Igor Timofeev 2015-11-20 12:06:53 +03:00
parent 2967e780d3
commit 88c4a3e2d0
2 changed files with 217 additions and 60 deletions

217
lib/syntax.lua Normal file
View File

@ -0,0 +1,217 @@
local gpu = require("component").gpu
local buffer = require("doubleBuffering")
local unicode = require("unicode")
local syntax = {}
----------------------------------------------------------------------------------------------------------------
--Стандартные цветовые схемы
syntax.colorSchemes = {
midnight = {
recommendedBackground = 0x262626,
text = 0xffffff,
strings = 0xff2024,
loops = 0xffff98,
comments = 0xa2ffb7,
boolean = 0xffcc66,
logic = 0xffcc66,
numbers = 0x24c0ff,
functions = 0xffcc66,
compares = 0xffff98,
},
sunrise = {
recommendedBackground = 0xffffff,
text = 0x262626,
strings = 0x880000,
loops = 0x24c0ff,
comments = 0xa2ffb7,
boolean = 0x19c0cc,
logic = 0x880000,
numbers = 0x24c0ff,
functions = 0x24c0ff,
compares = 0x880000,
},
}
--Текущая цветовая схема
local currentColorScheme = {}
--Шаблоны поиска
local patterns
--Размер массива шаблонов поиска
local sPatterns
----------------------------------------------------------------------------------------------------------------
--Пересчитать цвета шаблонов
--Приоритет поиска шаблонов снижается сверху вниз
local function definePatterns()
patterns = {
--Комментарии
{ pattern = "%-%-.*", color = currentColorScheme.comments, cutFromLeft = 0, cutFromRight = 0 },
--Строки
{ pattern = "\"[^\"\"]*\"", color = currentColorScheme.strings, cutFromLeft = 0, cutFromRight = 0 },
--Циклы, условия, объявления
{ pattern = "while ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "do$", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "do ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "end$", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "end ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "for ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = " in ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "repeat ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "if ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "then", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "until ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "return", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "local ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "function ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "else$", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "else ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = "elseif ", color = currentColorScheme.loops, cutFromLeft = 0, cutFromRight = 1 },
--Состояния переменной
{ pattern = "true", color = currentColorScheme.boolean, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "false", color = currentColorScheme.boolean, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "nil", color = currentColorScheme.boolean, cutFromLeft = 0, cutFromRight = 0 },
--Функции
{ pattern = "%s([%a%d%_%-%.]*)%(", color = currentColorScheme.functions, cutFromLeft = 0, cutFromRight = 1 },
--And, or, not, break
{ pattern = " and ", color = currentColorScheme.logic, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = " or ", color = currentColorScheme.logic, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = " not ", color = currentColorScheme.logic, cutFromLeft = 0, cutFromRight = 1 },
{ pattern = " break$", color = currentColorScheme.logic, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "^break", color = currentColorScheme.logic, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = " break ", color = currentColorScheme.logic, cutFromLeft = 0, cutFromRight = 0 },
--Числа
{ pattern = "%s(0x)(%w*)", color = currentColorScheme.numbers, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "(%s)([%d%.]*)", color = currentColorScheme.numbers, cutFromLeft = 0, cutFromRight = 0 },
--Сравнения и мат. операции
{ pattern = "<=", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = ">=", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "<", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = ">", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "==", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "~=", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "=", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "%+", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "%-", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "%*", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "%/", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "%.%.", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "%#", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
{ pattern = "#^", color = currentColorScheme.compares, cutFromLeft = 0, cutFromRight = 0 },
}
--Ну, и размер массива шаблонов тоже
sPatterns = #patterns
end
--Костыльная замена обычному string.find()
--Работает медленнее, но хотя бы поддерживает юникод
function unicode.find(str, pattern, init, plain)
-- checkArg(1, str, "string")
-- checkArg(2, pattern, "string")
-- checkArg(3, init, "number", "nil")
if init then
if init < 0 then
init = -#unicode.sub(str,init)
elseif init > 0 then
init = #unicode.sub(str,1,init-1)+1
end
end
a, b = string.find(str, pattern, init, plain)
if a then
local ap,bp = str:sub(1,a-1), str:sub(a,b)
a = unicode.len(ap)+1
b = a + unicode.len(bp)-1
return a,b
else
return a
end
end
--Проанализировать строку и создать на ее основе цветовую карту
function syntax.highlight(x, y, text, limit)
--Кароч вооот, хыыы
local searchFrom, starting, ending
--Загоняем в буффер всю строку базового цвета
buffer.text(x, y, currentColorScheme.text, limit and unicode.sub(text, 1, limit) or text)
limit = limit or math.huge
--Перебираем шаблоны
for i = #patterns, 1, -1 do
searchFrom = 1
--Перебираем весь текст, а то мало ли шаблон дохуя раз встречается
while true do
starting, ending = unicode.find(text, patterns[i].pattern, searchFrom)
if starting and ending then
if ending <= limit then
buffer.text(x + starting - 1, y, patterns[i].color, unicode.sub(text, starting, ending - patterns[i].cutFromRight))
searchFrom = ending + 1
else
buffer.text(x + starting - 1, y, patterns[i].color, unicode.sub(text, starting, limit))
break
end
else
break
end
end
end
end
--Объявить новую цветовую схему
function syntax.setColorScheme(colorScheme)
--Выбранная цветовая схема
currentColorScheme = colorScheme
--Пересчитываем шаблоны
definePatterns()
end
--Открыть файл для чтения и отобразить первые строки из него, чтобы чекнуть, как работает подсветка
function syntax.highlightFileForDebug(pathToFile)
--Получаем размер экрана
local xSize, ySize = gpu.getResolution()
--Очищаем экран рекомендуемым цветом
buffer.square(1, 1, xSize, ySize, currentColorScheme.recommendedBackground, currentColorScheme.text, " ")
buffer.draw(true)
--Открываем файлик
local file = io.open(pathToFile, "r")
--Счетчик строк
local lineCounter = 1
--Читаем строки
for line in file:lines() do
--Подсвечиваем строку и рисуем
syntax.highlight(2, lineCounter + 1, line)
--Счетчик в плюс
lineCounter = lineCounter + 1
--Разрываем цикл, если кол-во строк превысило высоту экрана
if lineCounter > ySize then break end
--ecs.wait()
end
--Закрываем файл
file:close()
buffer.draw()
end
----------------------------------------------------------------------------------------------------------------
--Стартовое объявление цветовой схемы при загрузке библиотеки
syntax.setColorScheme(syntax.colorSchemes.midnight)
--Епты бля!
syntax.highlightFileForDebug("MineOS/Applications/Highlight.app/Resources/TestFile.txt", "midnight")
return syntax

View File

@ -1,60 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
//Задаем стартовые константы - верхняя граница, нижняя граница, шаг итерации функции, значение самой функции
double upperBorder, lowerBorder, increment, functionValue, argumentValue;
//Запрашиваем значение переменных через консоль
Console.WriteLine(" ");
Console.WriteLine("Введите нижнюю границу отрезка:");
lowerBorder = Convert.ToDouble(Console.ReadLine());
Console.WriteLine(" ");
Console.WriteLine("Введите верхнюю границу отрезка:");
upperBorder = Convert.ToDouble(Console.ReadLine());
Console.WriteLine(" ");
Console.WriteLine("Введите шаг табуляции функции:");
increment = Convert.ToDouble(Console.ReadLine());
Console.WriteLine(" ");
//Задаем стартовое значение аргумента функции, эквивалентное нижней границе отрезка
argumentValue = lowerBorder;
//При помощи цикла выводим на экран значения функции при варьирующемся аргументе в зависимости от указанного инкремента
while (argumentValue <= upperBorder) {
//Смотрим на значение аргумента функции и выбираем нужную формулу расчета функции в зависимости от условий задачи
if (Math.Abs(argumentValue) < 2)
{
//Считаем значение функции
functionValue = Math.Pow(Math.Sin(5 * argumentValue), 3);
//Выводим на экран значение функции при текущем аргументе
Console.WriteLine("f(" + argumentValue + ") = Math.Pow(Math.Sin(5 * " + argumentValue + "), 3) = " + functionValue);
}
else
{
functionValue = Math.Exp(2 * argumentValue);
Console.WriteLine("f(" + argumentValue + ") = Math.Exp(2 * " + argumentValue + ") = " + functionValue);
}
//Прибавляем к значению аргумента значение инкремента
argumentValue = argumentValue + increment;
}
//Ожидаем нажатия клавиши. Костыль, но работает
Console.ReadKey();
}
}
}