This commit is contained in:
Бондарев Иван 2018-10-04 12:14:46 +02:00
parent c8efdf5d53
commit 1782cd7e96
17 changed files with 210 additions and 5 deletions

View file

@ -3466,6 +3466,11 @@ namespace PascalABCCompiler.PCU
return new compiled_constructor_call_as_constant(CreateCompiledConstructorCall(), null);
}
private default_operator_node_as_constant CreateDefaultOperatorAsConstant()
{
return new default_operator_node_as_constant(CreateDefaultOperator(), null);
}
private expression_node CreateExpression(semantic_node_type snt)
{
//location loc = ReadDebugInfo();
@ -3490,6 +3495,8 @@ namespace PascalABCCompiler.PCU
return CreateCommonNamespaceFunctionCallNodeAsConstant();
case semantic_node_type.compiled_constructor_call_as_constant:
return CreateCompiledConstructorCallAsConstant();
case semantic_node_type.default_operator_node_as_constant:
return CreateDefaultOperatorAsConstant();
case semantic_node_type.array_const:
return CreateArrayConst();
case semantic_node_type.record_const:
@ -3608,7 +3615,7 @@ namespace PascalABCCompiler.PCU
throw new Exception("Unknown expression "+snt);
}
private expression_node CreateDefaultOperator()
private default_operator_node CreateDefaultOperator()
{
return new default_operator_node(GetTypeReference(),null);
}

View file

@ -3615,6 +3615,8 @@ namespace PascalABCCompiler.PCU
VisitCommonConstructorCallAsConstant((common_constructor_call_as_constant)en); break;
case semantic_node_type.basic_function_call_node_as_constant:
VisitBasicFunctionCallAsConstant((basic_function_call_as_constant)en); break;
case semantic_node_type.default_operator_node_as_constant:
VisitDefaultOperatorAsConstant((default_operator_node_as_constant)en); break;
case semantic_node_type.array_initializer:
VisitArrayInitializer((array_initializer)en); break;
case semantic_node_type.record_initializer:
@ -3672,7 +3674,12 @@ namespace PascalABCCompiler.PCU
VisitBasicFunctionCall(expr.method_call);
}
private void VisitNamespaceConstantReference(namespace_constant_reference expr)
private void VisitDefaultOperatorAsConstant(default_operator_node_as_constant expr)
{
VisitDefaultOperator(expr.default_operator);
}
private void VisitNamespaceConstantReference(namespace_constant_reference expr)
{
WriteConstantReference(expr.constant);
}

View file

@ -10612,6 +10612,11 @@ namespace PascalABCCompiler.NETGenerator
else il.Emit(OpCodes.Ldsflda, fb);
}
public override void visit(IDefaultOperatorNodeAsConstant value)
{
value.DefaultOperator.visit(this);
}
public override void visit(ICommonConstructorCallAsConstant value)
{
value.ConstructorCall.visit(this);

View file

@ -641,6 +641,11 @@ namespace PascalABCCompiler.SemanticTree
public virtual void visit(ICommonNamespaceEventNode value)
{
}
public virtual void visit(IDefaultOperatorNodeAsConstant value)
{
}
}
}

View file

@ -297,6 +297,8 @@ namespace PascalABCCompiler.SemanticTree
void visit(ILambdaFunctionCallNode value);
void visit(ICommonNamespaceEventNode value);
void visit(IDefaultOperatorNodeAsConstant value);
}
}

View file

@ -1857,7 +1857,15 @@ namespace PascalABCCompiler.SemanticTree
get;
}
}
public interface IDefaultOperatorNodeAsConstant : IConstantNode
{
IDefaultOperatorNode DefaultOperator
{
get;
}
}
public interface ICompiledConstructorCallAsConstant : IConstantNode
{
ICompiledConstructorCall MethodCall

4
TestSuite/default1.pas Normal file
View file

@ -0,0 +1,4 @@
begin
assert(default(integer) = 0);
assert(default(string) = nil);
end.

View file

@ -0,0 +1,5 @@
function f(x: byte := default(byte)) := x;
begin
assert(f = 0);
end.

View file

@ -0,0 +1,66 @@
unit u_defaultparams1;
function test(a:integer; b: integer:=3): integer;
begin
Result := b;
end;
function test2(a: integer := 4): integer;
begin
Result := a;
end;
function test3(a: integer := 4; b: real := 2.3): integer;
begin
Result := a;
end;
function string.test(a: integer := 6): integer;
begin
Result := a;
end;
function ff(delim: string := ' '): string;
begin
Result := 'abc';
end;
procedure tt(str: string);
begin
assert(str = 'abc');
end;
procedure tt(i: integer);
begin
raise new Exception;
end;
type
TClass=class
function f(a: integer := 1; b: integer := 2): integer;
begin
Result:=2;
end;
end;
begin
assert(test3=4);
assert(test(2)=3);
assert(test(2,4)=4);
var j : integer := test2;
assert(j=4);
var i := test2;
assert(i = 4);
var s := 'abcd';
assert(s.test=6);
var k := s.test;
assert(k = 6);
tt(ff);
assert(ArrRandomReal <> nil);
assert(ArrRandomReal.Any = true);
var obj := new TClass;
var l := obj.f;
assert(l = 2);
end.

View file

@ -0,0 +1,6 @@
unit u_defaultparams2;
function f(x: byte := default(byte)) := x;
begin
assert(f = 0);
end.

View file

@ -0,0 +1,20 @@
uses u_defaultparams1;
begin
assert(test3=4);
assert(test(2)=3);
assert(test(2,4)=4);
var j : integer := test2;
assert(j=4);
var i := test2;
assert(i = 4);
var s := 'abcd';
assert(s.test=6);
var k := s.test;
assert(k = 6);
tt(ff);
assert(ArrRandomReal <> nil);
assert(ArrRandomReal.Any = true);
var obj := new TClass;
var l := obj.f;
assert(l = 2);
end.

View file

@ -0,0 +1,4 @@
uses u_defaultparams2;
begin
assert(f = 0);
end.

View file

@ -14232,6 +14232,8 @@ namespace PascalABCCompiler.TreeConverter
constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null);
return constant;
}
else if (expr is default_operator_node)
constant = new default_operator_node_as_constant(expr as default_operator_node, null);
else
{
constant = expr as constant_node;
@ -14258,6 +14260,7 @@ namespace PascalABCCompiler.TreeConverter
}
}
if (constant == null)
AddError(loc, "CONSTANT_EXPRESSION_EXPECTED");
if (IsBoundedArray(tn) || IsUnsizedArray(tn))

View file

@ -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
wrapped_statement, wrapped_expression, default_operator_node_as_constant
};
/// <summary>

View file

@ -1124,7 +1124,60 @@ namespace PascalABCCompiler.TreeRealization
}
}
}
public class default_operator_node_as_constant : constant_node, SemanticTree.IDefaultOperatorNodeAsConstant
{
private default_operator_node _default_operator;
public default_operator_node default_operator
{
get
{
return _default_operator;
}
set
{
_default_operator = value;
}
}
public default_operator_node_as_constant(default_operator_node default_operator, location loc)
:
base(default_operator.type, loc)
{
_default_operator = default_operator;
}
SemanticTree.IDefaultOperatorNode SemanticTree.IDefaultOperatorNodeAsConstant.DefaultOperator
{
get
{
return _default_operator;
}
}
/// <summary>
/// Метод для обхода дерева посетителем.
/// </summary>
/// <param name="visitor">Класс - посетитель дерева.</param>
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit(this);
}
/// <summary>
/// Тип узла.
/// </summary>
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.default_operator_node_as_constant;
}
}
}
public class compiled_constructor_call_as_constant : constant_node, SemanticTree.ICompiledConstructorCallAsConstant
{
private compiled_constructor_call _method_call;

View file

@ -1549,5 +1549,10 @@ namespace VisualPascalABCPlugins
public virtual void visit(ICommonNamespaceEventNode value)
{
}
public void visit(IDefaultOperatorNodeAsConstant value)
{
throw new System.NotImplementedException();
}
}
}

View file

@ -2555,5 +2555,10 @@ namespace VisualPascalABCPlugins
public virtual void visit(ICommonNamespaceEventNode value)
{
}
public void visit(IDefaultOperatorNodeAsConstant value)
{
throw new System.NotImplementedException();
}
}
}