fix #2330
This commit is contained in:
parent
b87ceaeff2
commit
460247ccc6
|
|
@ -6,6 +6,6 @@ namespace PascalABCCompiler.PCU
|
|||
{
|
||||
public static class PCUFileFormatVersion
|
||||
{
|
||||
public static System.Int16 Version = 116;
|
||||
public static System.Int16 Version = 117;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3502,7 +3502,12 @@ namespace PascalABCCompiler.PCU
|
|||
{
|
||||
return new question_colon_expression(CreateExpression(), CreateExpression(), CreateExpression(), null);
|
||||
}
|
||||
|
||||
|
||||
private double_question_colon_expression CreateDoubleQuestionColonExpression()
|
||||
{
|
||||
return new double_question_colon_expression(CreateExpression(), CreateExpression(), null);
|
||||
}
|
||||
|
||||
private statements_expression_node CreateStatementsExpressionNode()
|
||||
{
|
||||
statement_node_list sl = new statement_node_list();
|
||||
|
|
@ -3551,6 +3556,8 @@ namespace PascalABCCompiler.PCU
|
|||
return CreateStatementsExpressionNode();
|
||||
case semantic_node_type.question_colon_expression:
|
||||
return CreateQuestionColonExpression();
|
||||
case semantic_node_type.double_question_colon_expression:
|
||||
return CreateDoubleQuestionColonExpression();
|
||||
case semantic_node_type.sizeof_operator:
|
||||
return CreateSizeOfOperator();
|
||||
case semantic_node_type.is_node:
|
||||
|
|
|
|||
|
|
@ -3634,7 +3634,13 @@ namespace PascalABCCompiler.PCU
|
|||
VisitExpression(node.internal_ret_if_true);
|
||||
VisitExpression(node.internal_ret_if_false);
|
||||
}
|
||||
|
||||
|
||||
private void VisitDoubleQuestionColonExpression(double_question_colon_expression node)
|
||||
{
|
||||
VisitExpression(node.internal_condition);
|
||||
VisitExpression(node.internal_ret_if_null);
|
||||
}
|
||||
|
||||
private void VisitStatementsExpressionNode(statements_expression_node node)
|
||||
{
|
||||
bw.Write(node.internal_statements.Count);
|
||||
|
|
@ -3677,6 +3683,8 @@ namespace PascalABCCompiler.PCU
|
|||
VisitStatementsExpressionNode((statements_expression_node)en); break;
|
||||
case semantic_node_type.question_colon_expression:
|
||||
VisitQuestionColonExpression((question_colon_expression)en); break;
|
||||
case semantic_node_type.double_question_colon_expression:
|
||||
VisitDoubleQuestionColonExpression((double_question_colon_expression)en); break;
|
||||
case semantic_node_type.sizeof_operator:
|
||||
VisitSizeOfOperator((sizeof_operator)en); break;
|
||||
case semantic_node_type.is_node:
|
||||
|
|
|
|||
|
|
@ -10411,6 +10411,57 @@ namespace PascalABCCompiler.NETGenerator
|
|||
|
||||
}
|
||||
|
||||
public override void visit(IDoubleQuestionColonExpressionNode value)
|
||||
{
|
||||
Label EndLabel = il.DefineLabel();
|
||||
Label NullLabel = il.DefineLabel();
|
||||
bool tmp_is_dot_expr = is_dot_expr;
|
||||
bool tmp_is_addr = is_addr;
|
||||
is_dot_expr = false;//don't box the condition expression
|
||||
is_addr = false;
|
||||
LocalBuilder tmp_lb = null;
|
||||
if (value.condition is IBasicFunctionCallNode &&
|
||||
(value.condition as IBasicFunctionCallNode).real_parameters[0].type.IsDelegate &&
|
||||
(value.condition as IBasicFunctionCallNode).real_parameters[1] is INullConstantNode &&
|
||||
(value.condition as IBasicFunctionCallNode).basic_function.basic_function_type == basic_function_type.objeq)
|
||||
{
|
||||
IBasicFunctionCallNode eq = (value.condition as IBasicFunctionCallNode);
|
||||
tmp_lb = il.DeclareLocal(helper.GetTypeReference((value.condition as IBasicFunctionCallNode).real_parameters[0].type).tp);
|
||||
eq.real_parameters[0].visit(this);
|
||||
il.Emit(OpCodes.Stloc, tmp_lb);
|
||||
il.Emit(OpCodes.Ldloc, tmp_lb);
|
||||
il.Emit(OpCodes.Ldnull);
|
||||
il.Emit(OpCodes.Ceq);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
value.condition.visit(this);
|
||||
tmp_lb = il.DeclareLocal(helper.GetTypeReference(value.type).tp);
|
||||
il.Emit(OpCodes.Stloc, tmp_lb);
|
||||
il.Emit(OpCodes.Ldloc, tmp_lb);
|
||||
il.Emit(OpCodes.Ldnull);
|
||||
il.Emit(OpCodes.Ceq);
|
||||
}
|
||||
|
||||
|
||||
is_dot_expr = tmp_is_dot_expr;
|
||||
is_addr = tmp_is_addr;
|
||||
il.Emit(OpCodes.Brtrue, NullLabel);
|
||||
il.Emit(OpCodes.Ldloc, tmp_lb);
|
||||
TypeInfo ti = helper.GetTypeReference(value.condition.type);
|
||||
if (ti != null)
|
||||
EmitBox(value.condition, ti.tp);
|
||||
il.Emit(OpCodes.Br, EndLabel);
|
||||
il.MarkLabel(NullLabel);
|
||||
value.ret_if_null.visit(this);
|
||||
ti = helper.GetTypeReference(value.ret_if_null.type);
|
||||
if (ti != null)
|
||||
EmitBox(value.ret_if_null, ti.tp);
|
||||
il.MarkLabel(EndLabel);
|
||||
|
||||
}
|
||||
|
||||
private Hashtable range_stmts_labels = new Hashtable();
|
||||
|
||||
//перевод селекторов-диапазонов case
|
||||
|
|
|
|||
|
|
@ -646,6 +646,11 @@ namespace PascalABCCompiler.SemanticTree
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void visit(IDoubleQuestionColonExpressionNode value)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ namespace PascalABCCompiler.SemanticTree
|
|||
void visit(ICommonNamespaceEventNode value);
|
||||
|
||||
void visit(IDefaultOperatorNodeAsConstant value);
|
||||
}
|
||||
|
||||
void visit(IDoubleQuestionColonExpressionNode value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2241,7 +2241,20 @@ namespace PascalABCCompiler.SemanticTree
|
|||
}
|
||||
}
|
||||
|
||||
public interface ILabelNode : IDefinitionNode, ILocated
|
||||
public interface IDoubleQuestionColonExpressionNode : IExpressionNode
|
||||
{
|
||||
IExpressionNode condition
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
IExpressionNode ret_if_null
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ILabelNode : IDefinitionNode, ILocated
|
||||
{
|
||||
//Имя метки. Для языков не чувствительных к регистрам хранит имя в том виде, в каком тип объявлен.
|
||||
string name
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
return num.ToString();
|
||||
}
|
||||
|
||||
public override void visit(double_question_node dqn)
|
||||
/*public override void visit(double_question_node dqn)
|
||||
{
|
||||
var st = dqn.Parent;
|
||||
while (!(st is statement))
|
||||
|
|
@ -42,6 +42,6 @@ namespace SyntaxVisitors.SugarVisitors
|
|||
visit(qce);
|
||||
ReplaceStatementUsingParent(st as statement, l);
|
||||
visit(tt);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
@ -67,6 +67,9 @@ const
|
|||
/// Константа перехода на новую строку
|
||||
/// !! The newline string defined for this environment.
|
||||
NewLine = System.Environment.NewLine;
|
||||
/// Константа - символы-разделители слов
|
||||
/// !! symbols - word delimiters
|
||||
AllDelimiters = ' <>=^`|~$№§!"#%&''()*,+-./:;?@[\]_{}«·»'#9#10#13;
|
||||
//{{{--doc: Конец секции стандартных констант для документации }}}
|
||||
|
||||
|
||||
|
|
@ -4064,20 +4067,25 @@ function CharRange.Reverse: sequence of char := Range(l,h).Reverse;
|
|||
//------------------------------------------------------------------------------
|
||||
// Операции для string и char
|
||||
//------------------------------------------------------------------------------
|
||||
///--
|
||||
procedure string.operator+=(var left: string; right: string);
|
||||
begin
|
||||
left := left + right;
|
||||
end;
|
||||
|
||||
///--
|
||||
function string.operator<(left, right: string) := string.CompareOrdinal(left, right) < 0;
|
||||
|
||||
///--
|
||||
function string.operator<=(left, right: string) := string.CompareOrdinal(left, right) <= 0;
|
||||
|
||||
///--
|
||||
function string.operator>(left, right: string) := string.CompareOrdinal(left, right) > 0;
|
||||
|
||||
///--
|
||||
function string.operator>=(left, right: string) := string.CompareOrdinal(left, right) >= 0;
|
||||
|
||||
/// Повторяет строку str n раз
|
||||
///--
|
||||
function string.operator*(str: string; n: integer): string;
|
||||
begin
|
||||
var sb := new StringBuilder;
|
||||
|
|
@ -4086,7 +4094,7 @@ begin
|
|||
Result := sb.ToString;
|
||||
end;
|
||||
|
||||
/// Повторяет строку str n раз
|
||||
///--
|
||||
function string.operator*(n: integer; str: string): string;
|
||||
begin
|
||||
var sb := new StringBuilder;
|
||||
|
|
@ -4095,7 +4103,7 @@ begin
|
|||
Result := sb.ToString;
|
||||
end;
|
||||
|
||||
/// Повторяет символ c n раз
|
||||
///--
|
||||
function char.operator*(c: char; n: integer): string;
|
||||
begin
|
||||
if n <= 0 then
|
||||
|
|
@ -4109,7 +4117,7 @@ begin
|
|||
Result := sb.ToString;
|
||||
end;
|
||||
|
||||
/// Повторяет символ c n раз
|
||||
///--
|
||||
function char.operator*(n: integer; c: char): string;
|
||||
begin
|
||||
if n <= 0 then
|
||||
|
|
@ -4123,18 +4131,23 @@ begin
|
|||
Result := sb.ToString;
|
||||
end;
|
||||
|
||||
/// Добавляет к строке str строковое представление числа n
|
||||
// Добавляет к строке str строковое представление числа n
|
||||
///--
|
||||
function string.operator+(str: string; n: integer) := str + n.ToString;
|
||||
|
||||
/// Добавляет к строке str строковое представление числа n
|
||||
// Добавляет к строке str строковое представление числа n
|
||||
///--
|
||||
function string.operator+(n: integer; str: string) := n.ToString + str;
|
||||
|
||||
/// Добавляет к строке str строковое представление числа r
|
||||
// Добавляет к строке str строковое представление числа r
|
||||
///--
|
||||
function string.operator+(str: string; r: real) := str + r.ToString(nfi);
|
||||
|
||||
/// Добавляет к строке str строковое представление числа r
|
||||
// Добавляет к строке str строковое представление числа r
|
||||
///--
|
||||
function string.operator+(r: real; str: string) := r.ToString(nfi) + str;
|
||||
|
||||
///--
|
||||
procedure string.operator+=(var left: string; right: integer);
|
||||
begin
|
||||
left := left + right.ToString;
|
||||
|
|
@ -12349,10 +12362,10 @@ begin
|
|||
Result := Self.Split(delim, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
end;
|
||||
|
||||
const AllWordDelimiters = ' <>=^`|~$№§!"#%&''()*,+-./:;?@[\]_{}«·»'#9#10#13;
|
||||
const SpaceDelimiters = ' '+#9#10#13;
|
||||
|
||||
/// Преобразует строку в массив слов, используя в качестве разделителей символы из строки delim
|
||||
function ToWords(Self: string; delim: string := AllWordDelimiters): array of string; extensionmethod;
|
||||
function ToWords(Self: string; delim: string := SpaceDelimiters): array of string; extensionmethod;
|
||||
begin
|
||||
Result := Self.Split(delim.ToCharArray, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
end;
|
||||
|
|
@ -12859,59 +12872,59 @@ function operator>=<T1,T2,T3,T4,T5,T6,T7>(Self: (T1, T2, T3, T4,T5,T6,T7); v: (T
|
|||
// -------------------------------------------
|
||||
// Дополнения февраль 2016
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
/// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3>(Self: (T1, T2); v: T3): (T1, T2, T3); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0], Self[1], v);
|
||||
end;
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
/// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3, T4>(Self: (T1, T2, T3); v: T4): (T1, T2, T3, T4); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0], Self[1], Self[2], v);
|
||||
end;
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
/// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4); v: T5): (T1, T2, T3, T4, T5); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0], Self[1], Self[2], Self[3], v);
|
||||
end;
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
/// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3, T4, T5, T6>(Self: (T1, T2, T3, T4, T5); v: T6): (T1, T2, T3, T4, T5, T6); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0], Self[1], Self[2], Self[3], Self[4], v);
|
||||
end;
|
||||
|
||||
// Добавляет поле к кортежу
|
||||
/// Добавляет поле к кортежу
|
||||
function Add<T1, T2, T3, T4, T5, T6, T7>(Self: (T1, T2, T3, T4, T5, T6); v: T7): (T1, T2, T3, T4, T5, T6, T7); extensionmethod;
|
||||
begin
|
||||
Result := (Self[0], Self[1], Self[2], Self[3], Self[4], Self[5], v);
|
||||
end;
|
||||
|
||||
// Выводит кортеж
|
||||
/// Выводит кортеж
|
||||
procedure Print<T1, T2>(Self: (T1, T2)); extensionmethod := Print(Self);
|
||||
// Выводит кортеж
|
||||
/// Выводит кортеж
|
||||
procedure Print<T1, T2, T3>(Self: (T1, T2, T3)); extensionmethod := Print(Self);
|
||||
// Выводит кортеж
|
||||
/// Выводит кортеж
|
||||
procedure Print<T1, T2, T3, T4>(Self: (T1, T2, T3, T4)); extensionmethod := Print(Self);
|
||||
// Выводит кортеж
|
||||
/// Выводит кортеж
|
||||
procedure Print<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4, T5)); extensionmethod := Print(Self);
|
||||
// Выводит кортеж
|
||||
/// Выводит кортеж
|
||||
procedure Print<T1, T2, T3, T4, T5, T6>(Self: (T1, T2, T3, T4, T5, T6)); extensionmethod := Print(Self);
|
||||
// Выводит кортеж
|
||||
/// Выводит кортеж
|
||||
procedure Print<T1, T2, T3, T4, T5, T6, T7>(Self: (T1, T2, T3, T4, T5, T6, T7)); extensionmethod := Print(Self);
|
||||
// Выводит кортеж и переходит на новую строку
|
||||
/// Выводит кортеж и переходит на новую строку
|
||||
procedure Println<T1, T2>(Self: (T1, T2)); extensionmethod := Println(Self);
|
||||
// Выводит кортеж и переходит на новую строку
|
||||
/// Выводит кортеж и переходит на новую строку
|
||||
procedure Println<T1, T2, T3>(Self: (T1, T2, T3)); extensionmethod := Println(Self);
|
||||
// Выводит кортеж и переходит на новую строку
|
||||
/// Выводит кортеж и переходит на новую строку
|
||||
procedure Println<T1, T2, T3, T4>(Self: (T1, T2, T3, T4)); extensionmethod := Println(Self);
|
||||
// Выводит кортеж и переходит на новую строку
|
||||
/// Выводит кортеж и переходит на новую строку
|
||||
procedure Println<T1, T2, T3, T4, T5>(Self: (T1, T2, T3, T4, T5)); extensionmethod := Println(Self);
|
||||
// Выводит кортеж и переходит на новую строку
|
||||
/// Выводит кортеж и переходит на новую строку
|
||||
procedure Println<T1, T2, T3, T4, T5, T6>(Self: (T1, T2, T3, T4, T5, T6)); extensionmethod := Println(Self);
|
||||
// Выводит кортеж и переходит на новую строку
|
||||
/// Выводит кортеж и переходит на новую строку
|
||||
procedure Println<T1, T2, T3, T4, T5, T6, T7>(Self: (T1, T2, T3, T4, T5, T6, T7)); extensionmethod := Println(Self);
|
||||
|
||||
|
||||
|
|
|
|||
10
TestSuite/double_question1.pas
Normal file
10
TestSuite/double_question1.pas
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
begin
|
||||
var o := new object;
|
||||
var s := o ?? nil;
|
||||
assert(s = o);
|
||||
o := nil;
|
||||
s := o ?? new object;
|
||||
assert(s <> nil);
|
||||
var x := nil ?? 'abc';
|
||||
assert(x = 'abc');
|
||||
end.
|
||||
3
TestSuite/errors/err0382.pas
Normal file
3
TestSuite/errors/err0382.pas
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
begin
|
||||
var x := 'aaa'??2;
|
||||
end.
|
||||
3
TestSuite/errors/err0383.pas
Normal file
3
TestSuite/errors/err0383.pas
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
begin
|
||||
var x := 3??2;
|
||||
end.
|
||||
3
TestSuite/errors/err0384.pas
Normal file
3
TestSuite/errors/err0384.pas
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
begin
|
||||
var x := nil??nil;
|
||||
end.
|
||||
12
TestSuite/units/u_doublequestion1.pas
Normal file
12
TestSuite/units/u_doublequestion1.pas
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
unit u_doublequestion1;
|
||||
|
||||
begin
|
||||
var o := new object;
|
||||
var s := o ?? nil;
|
||||
assert(s = o);
|
||||
o := nil;
|
||||
s := o ?? new object;
|
||||
assert(s <> nil);
|
||||
var x := nil ?? 'abc';
|
||||
assert(x = 'abc');
|
||||
end.
|
||||
2
TestSuite/usesunits/use_doublequestion1.pas
Normal file
2
TestSuite/usesunits/use_doublequestion1.pas
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
//winonly
|
||||
uses u_doublequestion1; begin end.
|
||||
|
|
@ -18059,6 +18059,115 @@ namespace PascalABCCompiler.TreeConverter
|
|||
throw new NotSupportedError(get_location(_template_param_list));
|
||||
}
|
||||
|
||||
public override void visit(double_question_node node)
|
||||
{
|
||||
expression_node condition = convert_strong(node.left);
|
||||
|
||||
convertion_data_and_alghoritms.convert_type(new null_const_node(null_type_node.get_type_node(), condition.location), condition.type);
|
||||
expression_node left = condition;
|
||||
expression_node right = convert_strong(node.right);
|
||||
if (condition is null_const_node)
|
||||
convertion_data_and_alghoritms.convert_type(new null_const_node(null_type_node.get_type_node(), right.location), right.type);
|
||||
|
||||
try_convert_typed_expression_to_function_call(ref left);
|
||||
try_convert_typed_expression_to_function_call(ref right);
|
||||
|
||||
if (left is null_const_node && right.type.is_value_type)
|
||||
{
|
||||
if (right.type is compiled_type_node)
|
||||
{
|
||||
var rt = right.type as compiled_type_node;
|
||||
if (!rt.compiled_type.IsGenericType || rt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>))
|
||||
{
|
||||
right = convert_strong(ToNullable(node.right));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (right is null_const_node && left.type.is_value_type)
|
||||
{
|
||||
if (left.type is compiled_type_node)
|
||||
{
|
||||
var lt = left.type as compiled_type_node;
|
||||
if (!lt.compiled_type.IsGenericType || lt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>))
|
||||
{
|
||||
left = convert_strong(ToNullable(node.left));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*var typeComparisonResult = type_table.compare_types(left.type, right.type);
|
||||
if (typeComparisonResult == type_compare.greater_type)
|
||||
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||
else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/
|
||||
if (left is null_const_node)
|
||||
{
|
||||
left = convertion_data_and_alghoritms.convert_type(left, right.type);
|
||||
}
|
||||
else
|
||||
{
|
||||
delegated_methods del_left = left.type as delegated_methods;
|
||||
delegated_methods del_right = right.type as delegated_methods;
|
||||
if (del_left != null && del_right != null && del_left.empty_param_method == null && del_right.empty_param_method == null)
|
||||
{
|
||||
base_function_call bfc = del_left.proper_methods[0];
|
||||
common_type_node del =
|
||||
convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null);
|
||||
context.converted_namespace.types.AddElement(del);
|
||||
right = convertion_data_and_alghoritms.explicit_convert_type(right, del);
|
||||
left = convertion_data_and_alghoritms.explicit_convert_type(left, del);
|
||||
}
|
||||
else
|
||||
{
|
||||
var rtl = type_table.get_convertions(right.type, left.type);
|
||||
var ltr = type_table.get_convertions(left.type, right.type);
|
||||
|
||||
if (ltr.first != null && rtl.first == null)
|
||||
{
|
||||
left = convertion_data_and_alghoritms.convert_type(left, right.type);
|
||||
}
|
||||
else if (ltr.first == null && rtl.first != null)
|
||||
{
|
||||
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// если оба типа - целые
|
||||
if (convertion_data_and_alghoritms.is_value_int_type(left.type) && convertion_data_and_alghoritms.is_value_int_type(right.type))
|
||||
{
|
||||
var lub = convertion_data_and_alghoritms.least_upper_bound_value_int_type(left.type, right.type);
|
||||
if (lub == left.type)
|
||||
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||
else if (lub == right.type)
|
||||
left = convertion_data_and_alghoritms.convert_type(left, right.type);
|
||||
else
|
||||
{
|
||||
right = convertion_data_and_alghoritms.convert_type(right, lub);
|
||||
left = convertion_data_and_alghoritms.convert_type(right, lub);
|
||||
}
|
||||
}
|
||||
else if (left.type == SystemLibrary.SystemLibrary.float_type && right.type == SystemLibrary.SystemLibrary.double_type)
|
||||
left = convertion_data_and_alghoritms.convert_type(left, right.type);
|
||||
else if (right.type == SystemLibrary.SystemLibrary.float_type && left.type == SystemLibrary.SystemLibrary.double_type)
|
||||
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||
else if (left.type == right.type)
|
||||
{ }
|
||||
else // Это было - для совместимости. Что-то может не учтено
|
||||
{
|
||||
right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//right = convertion_data_and_alghoritms.convert_type(right, left.type);
|
||||
return_value(new double_question_colon_expression(condition, right, get_location(node)));
|
||||
}
|
||||
|
||||
public override void visit(SyntaxTree.question_colon_expression node)
|
||||
{
|
||||
expression_node condition = convert_strong(node.condition);
|
||||
|
|
|
|||
|
|
@ -340,7 +340,67 @@ namespace PascalABCCompiler.TreeRealization
|
|||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class double_question_colon_expression : expression_node, SemanticTree.IDoubleQuestionColonExpressionNode
|
||||
{
|
||||
private expression_node _condition;
|
||||
private expression_node _ret_if_null;
|
||||
|
||||
public double_question_colon_expression(expression_node condition, expression_node ret_if_null,
|
||||
location loc)
|
||||
: base(condition is null_const_node ? ret_if_null.type : condition.type, loc)
|
||||
{
|
||||
this._condition = condition;
|
||||
this._ret_if_null = ret_if_null;
|
||||
}
|
||||
|
||||
public expression_node internal_condition
|
||||
{
|
||||
get
|
||||
{
|
||||
return _condition;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public expression_node internal_ret_if_null
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ret_if_null;
|
||||
}
|
||||
}
|
||||
|
||||
public SemanticTree.IExpressionNode condition
|
||||
{
|
||||
get
|
||||
{
|
||||
return _condition;
|
||||
}
|
||||
}
|
||||
|
||||
public SemanticTree.IExpressionNode ret_if_null
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ret_if_null;
|
||||
}
|
||||
}
|
||||
|
||||
public override semantic_node_type semantic_node_type
|
||||
{
|
||||
get
|
||||
{
|
||||
return semantic_node_type.double_question_colon_expression;
|
||||
}
|
||||
}
|
||||
|
||||
public override void visit(SemanticTree.ISemanticVisitor visitor)
|
||||
{
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class array_initializer : expression_node, SemanticTree.IArrayInitializer
|
||||
{
|
||||
private List<expression_node> _element_values;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace PascalABCCompiler.TreeRealization
|
|||
common_constructor_call_as_constant, array_initializer, record_initializer, default_operator, attribute_node,
|
||||
pinvoke_node, basic_function_call_node_as_constant, compiled_static_field_reference_as_constant,
|
||||
common_namespace_event, indefinite_definition_node, indefinite_type, indefinite_function_call, indefinite_reference,
|
||||
wrapped_statement, wrapped_expression, default_operator_node_as_constant
|
||||
wrapped_statement, wrapped_expression, default_operator_node_as_constant, double_question_colon_expression
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1554,5 +1554,10 @@ namespace VisualPascalABCPlugins
|
|||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void visit(IDoubleQuestionColonExpressionNode value)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2560,5 +2560,10 @@ namespace VisualPascalABCPlugins
|
|||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void visit(IDoubleQuestionColonExpressionNode value)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue