Индивидуальные задания
Везде в [ ] указано число баллов за каждое задание
disclaimer требования к заданию описаны не полностью и должны уточняться по ходу работы (git pull request, комментарии к коммитам, тестам и т.п.)
1. Переменные и области видимости [40]
begin
var c;
c = 1;
begin
var c;
c = 2; // используется локальная c
write(c);
end;
end
begin
var c;
c = 1;
begin
var c = 3;
c = 2;
write(global c); // global указывает, что используется "с" объявленная во внешнем блоке
var m = global c;
write(2*m*c);
end;
end
- [5] Добавить проверку областей видимости переменных. Необъявленные и повторно объявленные переменные должны приводить к ошибке. Для этого добавить таблицу символов.
- [10] Добавить области видимости переменных в генератор кода
- [3] Добавить инициализаторы переменных
- [7] Добавить поддержку global во все проходы компилятора
- [15] Создать визитор, который бы переносил все переменные в самую верхнюю возможную область видимости (c учетом конфликтов)
2. Метки, goto и таблица символов [40]
begin
l: write(0);
l1: write(1);
goto l;
goto ll; // ошибка
end
begin
l: a = -2;
l1: a = a + 1;
if a then goto l1;
exit; // завершает выполнение
goto l; // этот оператор никода не выполнится
end
- [5] Добавить метки в лексер, парсер и prettyprinter
- [4] Добавить таблицу символов и проверку корректности имен меток в goto
- [6] Добавить визитор, который преобразует циклы cycle в goto и if
- [9] Добавить визитор, который строит управляющий граф программы
- [10] Добавить поддержку меток в генератор IL-кода
- [6] Добавить оператор exit и поиск недостижимого кода
3. Функции и параметры
function f(a,b,c)
begin
return a+b-c;
end
begin
var a,b,c;
write(f(a,b,c));
end
- добавить функции в лексер и парсер
- добавить передачу параметров по ссылке (@a)
- добавить визитор, который строит граф вызовов
- добавить функции в генератор кода (можно без генерации собственно функций)
4. Массивы, указатели и срезы
begin
var a[10], b[3], c[4];
write(a[1]);
b = a[:4];
c = a[7:];
с = a[0:3:]; // начина с 1 с шагом 3
end
- добавить поддержку статических массивов (определение и описание) в лексер и парсер
- добавить поддержку срезов массивов в лексер и парсер
- добавить проверку совпадения размерностей массивов в выражениях (включая срезы). Например, c[0:4] = a[0:3:9] + b, но не c[0:4] = a[0:3:9] + c
- добавить поддержку статических массивов в генератор кода (без срезов)
5. вывод типов?
6. типизированные массивы
begin
int a[10];
bool b[10];
float f[10];
end
7. встроенные типы, проверка типов
8. структуры
9. классы с методами
10. функции-генераторы
11. циклы по массиву
- поддержка var A[N]; cycle a in A s += a end; в лексер и парсер
- ...
12. функции и области видимости
13. модули и файлы
// file1.toy
module mymodule
public foo(a,b,c);
public goo(x,y);
begin
function foo(a,b,c)
begin
end;
function goo(a,b,c)
begin
end;
end
// file2.toy
from file1.toy import mymodule as mo;
begin
write(mo.foo(mo.goo(),1,1));
end;
- добавить все необходимое в лексер и парсер
- добавить проход "линковки" модулей в AST после их синтаксического разбора.
- добавить эту функциональность в генератор кода
14. препроцессор, макросы и прагмы
#inlude otherfile.toy
#def N 100
#def yes
begin
#if yes
var a,b;
#else
#end
# def foo %1+%2
# pragma tostderr // эта прагма должна заставить write вывести сообщение в стандартный поток ошибок
write(foo(a,b))
end
- препроцессор
- макросы
- прагмы (включая изменения в генераторе кода)
- include
15. шаблоны функций (элементарные)
16. lambda
17. функции, inlining
18. функции, передача параметров по ссылке
19. функции, предусловия и постусловия
20. интерпретация
21. структуры и полноправные функции
function foo(a,b,c)
begin
return object(
a -> a,
my_b -> b,
my_c -> function(x,y)
begin
return (x*self.a - y*self.my_b)*c;
end
);
end
begin
obj = foo(1,2,3);
write(obj.my_c(2,2));
end
- лексер и парсер (функции)
- лексер и парсер (структуры)
- pretty printer
- интерпретатор?
21. списки
22. функции и атрибуты для операторов
attribute onaccess
???
end;
function warn(x)
begin
end;
begin
#onaccess<warn>
var a,b,c;
end
23. генераторы
begin
write(a) for a in M;
end
24. перегрузка функций
- типы переменных
- функции с типизированными параметрами и их вызов
- проверка соответствия типов формальных и фактических параметров
- перегрузка функций, проверка наличия подходящей функции и вывод ошибок
25. строковые операции
begin
a = 'string1';
b = 'string2';
c = (a + b + c[2]).substr(0,3);
write(c.toupper());
end
26. наследование функций
// функция всегда возвращает значение self т.е. ссылку на себя
// все поля предка доступны в потомке
// создание новой функции происходит при указании имени без параметров
function foo(a)
self.m_a = a;
write(a);
end;
function goo(b) from foo
write(b + self.m_a)
end;
begin
var f = foo;
var g = goo;
foo(1);
goo(2);
foo.a = 3;
goo(2);
end
27.
28.
29.
EasyFlow - язык описания составных приложений
30. Транслятор в JavaScript [17]
begin
var a,b,c;
a = 0;
b = 2;
c = 3;
if a then
a = 0
else a = b+c;
write(a)
end
нужно перевести в исполняемый код на JavaScript:
// var a,b,c;
// a = 0; b = 2; c = 3;
let a = 0, b = 2, c = 3;
if (a) {
a = 0;
} else {
a = b+c;
}
console.log(a);
- [10] Написать визитор, переводящий AST в программу на JavaScript
- [7] Добавить проход, позволяющий найти инициализаторы переменных и выводить их в JS в один оператор
30. Транслятор в C# [17]
begin
var a,b,c;
a = 0;
b = 2;
c = 3;
if a then
a = 0
else a = b+c;
write(a)
end
нужно перевести в исполняемый код на C#:
using System;
namespace default {
public class MainClass {
public static void main(string[] args) {
// int a,b,c;
// a = 0; b = 2; c = 3;
var a = 0, b = 2, c = 3;
if (a != 0) {
a = 0;
} else {
a = b+c;
}
Console.WriteLine(a);
}
}
}
- [10] Написать визитор, переводящий AST в программу на C#
- [7] Добавить проход, позволяющий найти инициализаторы переменных и выводить их в C# в один оператор