узел sugared_addressed_value - для slice_expr
This commit is contained in:
parent
ac9f0221b0
commit
6779e4d62c
|
|
@ -23,7 +23,7 @@ namespace PascalABCCompiler.SyntaxTreeConverters
|
|||
AssignTuplesDesugarVisitor.New.ProcessNode(root);
|
||||
|
||||
// Пока не доделали
|
||||
//SliceQuestionDesugarVisitor.New.ProcessNode(root);
|
||||
SliceQuestionDesugarVisitor.New.ProcessNode(root);
|
||||
|
||||
// Всё, связанное с yield
|
||||
root.visit(new MarkMethodHasYieldAndCheckSomeErrorsVisitor());
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,11 @@ namespace PascalABCCompiler.SyntaxTree
|
|||
{
|
||||
DefaultVisit(_sugared_expression);
|
||||
}
|
||||
|
||||
public virtual void visit(sugared_addressed_value _sugared_addressed_value)
|
||||
{
|
||||
DefaultVisit(_sugared_addressed_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
|
@ -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); // обойти заменённое на предмет наличия такого же синтаксического сахара
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
Loading…
Reference in a new issue