узел sugared_addressed_value - для slice_expr

This commit is contained in:
miks1965 2017-01-21 00:33:12 +03:00
parent ac9f0221b0
commit 6779e4d62c
12 changed files with 312 additions and 13 deletions

View file

@ -23,7 +23,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters
AssignTuplesDesugarVisitor.New.ProcessNode(root);
// Пока не доделали
//SliceQuestionDesugarVisitor.New.ProcessNode(root);
SliceQuestionDesugarVisitor.New.ProcessNode(root);
// Всё, связанное с yield
root.visit(new MarkMethodHasYieldAndCheckSomeErrorsVisitor());

View file

@ -1107,6 +1107,11 @@ namespace PascalABCCompiler.SyntaxTree
{
DefaultVisit(_sugared_expression);
}
public virtual void visit(sugared_addressed_value _sugared_addressed_value)
{
DefaultVisit(_sugared_addressed_value);
}
}

View file

@ -1765,6 +1765,14 @@ namespace PascalABCCompiler.SyntaxTree
{
}
public virtual void pre_do_visit(sugared_addressed_value _sugared_addressed_value)
{
}
public virtual void post_do_visit(sugared_addressed_value _sugared_addressed_value)
{
}
public override void visit(syntax_tree_node _syntax_tree_node)
{
DefaultVisit(_syntax_tree_node);
@ -3645,6 +3653,14 @@ namespace PascalABCCompiler.SyntaxTree
visit(sugared_expression.new_expr);
post_do_visit(_sugared_expression);
}
public override void visit(sugared_addressed_value _sugared_addressed_value)
{
DefaultVisit(_sugared_addressed_value);
pre_do_visit(_sugared_addressed_value);
visit(sugared_addressed_value.new_addr_value);
post_do_visit(_sugared_addressed_value);
}
}

View file

@ -460,6 +460,8 @@ namespace PascalABCCompiler.SyntaxTree
return new semantic_check_sugared_statement_node();
case 219:
return new sugared_expression();
case 220:
return new sugared_addressed_value();
}
return null;
}
@ -3873,6 +3875,19 @@ namespace PascalABCCompiler.SyntaxTree
_sugared_expression.new_expr = _read_node() as expression;
}
public void visit(sugared_addressed_value _sugared_addressed_value)
{
read_sugared_addressed_value(_sugared_addressed_value);
}
public void read_sugared_addressed_value(sugared_addressed_value _sugared_addressed_value)
{
read_addressed_value(_sugared_addressed_value);
_sugared_addressed_value.sugared_expr = (object)br.ReadByte();
_sugared_addressed_value.new_addr_value = _read_node() as addressed_value;
}
}

View file

@ -6038,6 +6038,28 @@ namespace PascalABCCompiler.SyntaxTree
}
}
public void visit(sugared_addressed_value _sugared_addressed_value)
{
bw.Write((Int16)220);
write_sugared_addressed_value(_sugared_addressed_value);
}
public void write_sugared_addressed_value(sugared_addressed_value _sugared_addressed_value)
{
write_addressed_value(_sugared_addressed_value);
bw.Write((byte)_sugared_addressed_value.sugared_expr);
if (_sugared_addressed_value.new_addr_value == null)
{
bw.Write((byte)0);
}
else
{
bw.Write((byte)1);
_sugared_addressed_value.new_addr_value.visit(this);
}
}
}

View file

@ -38647,7 +38647,7 @@ namespace PascalABCCompiler.SyntaxTree
///<summary>
///
///Обёртка для сахарного выражения, хранящего сахарный узел для семантических проверок и новое выражение после удаления синтаксического сахара
///</summary>
[Serializable]
public partial class sugared_expression : expression
@ -38801,6 +38801,161 @@ namespace PascalABCCompiler.SyntaxTree
}
///<summary>
///Обёртка для сахарного адресуемого значения, хранящего сахарный узел для семантических проверок и новое выражение после удаления синтаксического сахара
///</summary>
[Serializable]
public partial class sugared_addressed_value : addressed_value
{
///<summary>
///Конструктор без параметров.
///</summary>
public sugared_addressed_value()
{
}
///<summary>
///Конструктор с параметрами.
///</summary>
public sugared_addressed_value(object _sugared_expr,addressed_value _new_addr_value)
{
this._sugared_expr=_sugared_expr;
this._new_addr_value=_new_addr_value;
}
///<summary>
///Конструктор с параметрами.
///</summary>
public sugared_addressed_value(object _sugared_expr,addressed_value _new_addr_value,SourceContext sc)
{
this._sugared_expr=_sugared_expr;
this._new_addr_value=_new_addr_value;
source_context = sc;
}
protected object _sugared_expr;
protected addressed_value _new_addr_value;
///<summary>
///
///</summary>
public object sugared_expr
{
get
{
return _sugared_expr;
}
set
{
_sugared_expr=value;
}
}
///<summary>
///
///</summary>
public addressed_value new_addr_value
{
get
{
return _new_addr_value;
}
set
{
_new_addr_value=value;
}
}
/// <summary> Создает копию узла </summary>
public override syntax_tree_node Clone()
{
sugared_addressed_value copy = new sugared_addressed_value();
copy.Parent = this.Parent;
if (source_context != null)
copy.source_context = new SourceContext(source_context);
if (attributes != null)
{
copy.attributes = (attribute_list)attributes.Clone();
copy.attributes.Parent = copy;
}
copy.sugared_expr = sugared_expr;
if (new_addr_value != null)
{
copy.new_addr_value = (addressed_value)new_addr_value.Clone();
copy.new_addr_value.Parent = copy;
}
return copy;
}
/// <summary> Получает копию данного узла корректного типа </summary>
public new sugared_addressed_value TypedClone()
{
return Clone() as sugared_addressed_value;
}
///<summary>
///Свойство для получения количества всех подузлов без элементов поля типа List
///</summary>
public override Int32 subnodes_without_list_elements_count
{
get
{
return 1;
}
}
///<summary>
///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List
///</summary>
public override Int32 subnodes_count
{
get
{
return 1;
}
}
///<summary>
///Индексатор для получения всех подузлов
///</summary>
public override syntax_tree_node this[Int32 ind]
{
get
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
return new_addr_value;
}
return null;
}
set
{
if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1)
throw new IndexOutOfRangeException();
switch(ind)
{
case 0:
new_addr_value = (addressed_value)value;
break;
}
}
}
///<summary>
///Метод для обхода дерева посетителем
///</summary>
///<param name="visitor">Объект-посетитель.</param>
///<returns>Return value is void</returns>
public override void visit(IVisitor visitor)
{
visitor.visit(this);
}
}
}

View file

@ -1324,6 +1324,12 @@ namespace PascalABCCompiler.SyntaxTree
///<param name="_sugared_expression">Node to visit</param>
///<returns> Return value is void </returns>
void visit(sugared_expression _sugared_expression);
///<summary>
///Method to visit sugared_addressed_value.
///</summary>
///<param name="_sugared_addressed_value">Node to visit</param>
///<returns> Return value is void </returns>
void visit(sugared_addressed_value _sugared_addressed_value);
}

Binary file not shown.

View file

@ -42,12 +42,25 @@ namespace SyntaxVisitors.SugarVisitors
return el;
}
public override void visit(slice_expr sl)
{
var el = construct_expression_list_for_slice_expr(sl);
var mc = new method_call(new dot_node(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context);
var sug = new sugared_addressed_value(sl, mc, sl.source_context);
ReplaceUsingParent(sl, sug);
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
}
public override void visit(slice_expr_question sl)
{
var el = construct_expression_list_for_slice_expr(sl);
var mc = new method_call(new dot_node(sl.v, new ident("SystemSliceQuestion", sl.v.source_context), sl.v.source_context), el, sl.source_context);
ReplaceUsingParent(sl, mc);
var sug = new sugared_addressed_value(sl, mc, sl.source_context);
ReplaceUsingParent(sl, sug);
visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара
}

View file

@ -10,10 +10,10 @@ namespace PascalABCCompiler.TreeConverter
{
public partial class syntax_tree_visitor
{
public void semantic_check_sugared_statement(SyntaxTree.assign_tuple assvartup) // подходит и для assign_var_tuple
public void semantic_check_assign_tuple(SyntaxTree.assign_tuple asstup) // подходит и для assign_var_tuple
{
// Проверить, что справа - Tuple
var expr = convert_strong(assvartup.expr);
var expr = convert_strong(asstup.expr);
expr = convert_if_typed_expression_to_function_call(expr);
var t = ConvertSemanticTypeNodeToNETType(expr.type);
@ -23,9 +23,50 @@ namespace PascalABCCompiler.TreeConverter
if (!t.FullName.StartsWith("System.Tuple"))
AddError(expr.location, "TUPLE_EXPECTED");
var n = assvartup.vars.variables.Count();
var n = asstup.vars.variables.Count();
if (n > t.GetGenericArguments().Count())
AddError(get_location(assvartup.vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
AddError(get_location(asstup.vars), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT");
}
void semantic_check_slice_expr(SyntaxTree.slice_expr sl)
{
var semvar = convert_strong(sl.v);
if (semvar is typed_expression)
semvar = convert_typed_expression_to_function_call(semvar as typed_expression);
var t = ConvertSemanticTypeNodeToNETType(semvar.type);
var IsSlicedType = 0; // проверим, является ли semvar.type динамическим массивом, списком List или строкой
// semvar.type должен быть array of T, List<T> или string
if (t == null)
IsSlicedType = 0; // можно ничего не присваивать :)
else if (t.IsArray)
IsSlicedType = 1;
else if (t == typeof(System.String))
IsSlicedType = 2;
else if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>))
IsSlicedType = 3;
if (IsSlicedType == 0)
AddError(get_location(sl.v), "BAD_SLICE_OBJECT");
var semfrom = convert_strong(sl.from);
var b = convertion_data_and_alghoritms.can_convert_type(semfrom, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.from), "INTEGER_VALUE_EXPECTED");
var semto = convert_strong(sl.to);
b = convertion_data_and_alghoritms.can_convert_type(semto, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.to), "INTEGER_VALUE_EXPECTED");
if (sl.step != null)
{
var semstep = convert_strong(sl.step);
b = convertion_data_and_alghoritms.can_convert_type(semstep, SystemLibrary.SystemLibrary.integer_type);
if (!b)
AddError(get_location(sl.step), "INTEGER_VALUE_EXPECTED");
}
}
}
}

View file

@ -19144,9 +19144,9 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.assign_tuple asstup)
{
AddError(get_location(asstup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", typeof(assign_var_tuple).Name);
AddError(get_location(asstup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", asstup.GetType().Name);
/*check_sugared(asstup);
/*semantic_check_assign_tuple(asstup);
var tname = "#temp_var" + UniqueNumStr();
@ -19169,7 +19169,7 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.assign_var_tuple assvartup)
{
AddError(get_location(assvartup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", typeof(assign_var_tuple).Name);
AddError(get_location(assvartup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", assvartup.GetType().Name);
/*check_sugared(assvartup);
@ -19227,6 +19227,8 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.slice_expr sl)
{
//AddError(get_location(sl), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", sl.GetType().Name);
// Преобразуется в вызов a.SystemSlice(situation,from,to,step)
// Тип a должен быть array of T, List<T> или string
semcheck(sl);
@ -19240,6 +19242,8 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.slice_expr_question sl)
{
//AddError(get_location(sl), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", sl.GetType().Name);
// Преобразуется в вызов a.SystemSlice(situation,from,to,step)
// Тип a должен быть array of T, List<T> или string
semcheck(sl);
@ -19419,7 +19423,7 @@ namespace PascalABCCompiler.TreeConverter
{
if (st.stat is SyntaxTree.assign_tuple)
{
semantic_check_sugared_statement(st.stat as SyntaxTree.assign_tuple);
semantic_check_assign_tuple(st.stat as SyntaxTree.assign_tuple);
}
else
{
@ -19430,8 +19434,30 @@ namespace PascalABCCompiler.TreeConverter
public override void visit(SyntaxTree.sugared_expression ex)
{
//semantic_check_sugared_expression(ex.sugared_expr);
visit(ex.new_expr);
/*if (ex.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question
{
//semantic_check_slice_expr(ex.sugared_expr as SyntaxTree.slice_expr);
}
else*/
{
AddError(get_location(ex), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}");
}
ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя!
}
public override void visit(SyntaxTree.sugared_addressed_value av)
{
if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question
{
semantic_check_slice_expr(av.sugared_expr as SyntaxTree.slice_expr);
}
else
{
AddError(get_location(av), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}");
}
ProcessNode(av.new_addr_value); // обойти десахарное
}
/*public SyntaxTree.question_colon_expression ConvertToQCE(dot_question_node dqn)

Binary file not shown.