This commit is contained in:
miks1965 2018-10-02 17:53:43 +03:00
parent 0549048850
commit 1b0077eab7
11 changed files with 76 additions and 16 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3"; public const string Major = "3";
public const string Minor = "4"; public const string Minor = "4";
public const string Build = "2"; public const string Build = "2";
public const string Revision = "1809"; public const string Revision = "1812";
public const string MainVersion = Major + "." + Minor; public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=2
%REVISION%=1809
%MINOR%=4 %MINOR%=4
%REVISION%=1812
%COREVERSION%=2
%MAJOR%=3 %MAJOR%=3

Binary file not shown.

View file

@ -1 +1 @@
!define VERSION '3.4.2.1809' !define VERSION '3.4.2.1812'

View file

@ -55,9 +55,10 @@ namespace PascalABCCompiler.SyntaxTree
public void ReplaceStatementUsingParent(statement from, IEnumerable<statement> to, Desc d = Desc.DirectDescendants) public void ReplaceStatementUsingParent(statement from, IEnumerable<statement> to, Desc d = Desc.DirectDescendants)
{ {
var fp = from.Parent; // SSM 02.10.18 - запомним, т.к. from.Parent может быть одним из x.Parent
foreach (var x in to) foreach (var x in to)
x.Parent = from.Parent; x.Parent = fp;
var sl = from.Parent as statement_list; var sl = fp as statement_list;
if (sl != null) if (sl != null)
{ {
sl.ReplaceInList(from, to); sl.ReplaceInList(from, to);
@ -67,7 +68,7 @@ namespace PascalABCCompiler.SyntaxTree
var l = new statement_list(); var l = new statement_list();
l.AddMany(to); l.AddMany(to);
l.source_context = from.source_context; l.source_context = from.source_context;
from.Parent.ReplaceDescendant(from, l, d); fp.ReplaceDescendant(from, l, d);
} }
} }
} }

View file

@ -2181,7 +2181,7 @@ procedure __FinalizeModule__;
// DQNToNullable for dot_question_node // DQNToNullable for dot_question_node
// ----------------------------------------------------- // -----------------------------------------------------
function DQNToNullable(v: integer): Nullable<integer>; function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
implementation implementation
@ -11423,9 +11423,9 @@ end;
// DQNToNullable for dot_question_node: implementation // DQNToNullable for dot_question_node: implementation
// ----------------------------------------------------- // -----------------------------------------------------
function DQNToNullable(v: integer): System.Nullable<integer>; function DQNToNullable<T>(v: T): System.Nullable<T>; where T: record;
begin begin
Result := new System.Nullable<integer>(v); Result := new System.Nullable<T>(v);
end; end;
initialization initialization

View file

@ -1,9 +1,10 @@
function DQNToNullable<T>(v: T): T; where T: record; {function DQNToNullable<T>(v: T): T; where T: record;
begin begin
var res := new System.Nullable<T>(v); var res := new System.Nullable<T>(v);
Result := res.Value; Result := res.Value;
end; end;}
begin begin
assert(DQNToNullable(2) = 2); var t := DQNToNullable(2);
assert(t.Value = 2);
end. end.

View file

@ -0,0 +1,13 @@
type
TClass = class
fByte: byte := 2;
end;
begin
var x: TClass := new TClass;
var xxx1 := x=nil ? nil : x.fByte;
var xxx := x?.fByte;
Assert(xxx.Value=2);
Assert(xxx1.Value=2);
end.

View file

@ -0,0 +1,6 @@
begin
var o: object;
if false then
raise new Exception( (o?.GetType).ToString);
Assert(1=1);
end.

View file

@ -17284,14 +17284,42 @@ namespace PascalABCCompiler.TreeConverter
condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type);
expression_node left = convert_strong(node.ret_if_true); expression_node left = convert_strong(node.ret_if_true);
expression_node right = convert_strong(node.ret_if_false); expression_node right = convert_strong(node.ret_if_false);
try_convert_typed_expression_to_function_call(ref left); try_convert_typed_expression_to_function_call(ref left);
try_convert_typed_expression_to_function_call(ref right); 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.ret_if_false));
}
}
}
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.ret_if_true));
}
}
}
/*var typeComparisonResult = type_table.compare_types(left.type, right.type); /*var typeComparisonResult = type_table.compare_types(left.type, right.type);
if (typeComparisonResult == type_compare.greater_type) if (typeComparisonResult == type_compare.greater_type)
right = convertion_data_and_alghoritms.convert_type(right, left.type); right = convertion_data_and_alghoritms.convert_type(right, left.type);
else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/ else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/
if (left is null_const_node) if (left is null_const_node)
{
left = convertion_data_and_alghoritms.convert_type(left, right.type); left = convertion_data_and_alghoritms.convert_type(left, right.type);
}
else else
{ {
delegated_methods del_left = left.type as delegated_methods; delegated_methods del_left = left.type as delegated_methods;
@ -19811,6 +19839,12 @@ namespace PascalABCCompiler.TreeConverter
ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя! ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя!
} }
public method_call ToNullable(expression e)
{
var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable"));
return new method_call(dn, new expression_list(e), e.source_context);
}
public override void visit(SyntaxTree.sugared_addressed_value av) public override void visit(SyntaxTree.sugared_addressed_value av)
{ {
if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question
@ -19827,6 +19861,11 @@ namespace PascalABCCompiler.TreeConverter
var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable"));
(av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false (av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false
= new method_call(dn, new expression_list((av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false), av.source_context); = new method_call(dn, new expression_list((av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false), av.source_context);
/*var avqce = av.new_addr_value as SyntaxTree.question_colon_expression;
//var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable"));
avqce.ret_if_false = ToNullable(avqce.ret_if_false);
//new method_call(dn, new expression_list(avqce.ret_if_false), av.source_context);*/
} }
semantic_check_dot_question(av.new_addr_value as SyntaxTree.question_colon_expression); semantic_check_dot_question(av.new_addr_value as SyntaxTree.question_colon_expression);
} }

View file

@ -2181,7 +2181,7 @@ procedure __FinalizeModule__;
// DQNToNullable for dot_question_node // DQNToNullable for dot_question_node
// ----------------------------------------------------- // -----------------------------------------------------
function DQNToNullable(v: integer): Nullable<integer>; function DQNToNullable<T>(v: T): Nullable<T>; where T: record;
implementation implementation
@ -11423,9 +11423,9 @@ end;
// DQNToNullable for dot_question_node: implementation // DQNToNullable for dot_question_node: implementation
// ----------------------------------------------------- // -----------------------------------------------------
function DQNToNullable(v: integer): System.Nullable<integer>; function DQNToNullable<T>(v: T): System.Nullable<T>; where T: record;
begin begin
Result := new System.Nullable<integer>(v); Result := new System.Nullable<T>(v);
end; end;
initialization initialization