SPython: неявное преобразование int в bool и bool в int (#3383)

* Implement bool to int and int to bool implicit conversion for SPython

* Change "and", "or" and "not" operations to be logical in SPython

* Add standard functions' overloads (all, any, sum)
This commit is contained in:
Александр Земляк 2026-02-02 12:01:18 +03:00 committed by GitHub
parent dad4bf4f4b
commit 2c30b73b08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 187 additions and 71 deletions

View file

@ -506,11 +506,15 @@ expr
} }
| expr AND expr | expr AND expr
{ {
$$ = new bin_expr($1, $3, $2.type, @$); $$ = new bin_expr(SubtreeCreator.CreateMethodCall("bool", $1.source_context, $1),
SubtreeCreator.CreateMethodCall("bool", $3.source_context, $3),
$2.type, @$);
} }
| expr OR expr | expr OR expr
{ {
$$ = new bin_expr($1, $3, $2.type, @$); $$ = new bin_expr(SubtreeCreator.CreateMethodCall("bool", $1.source_context, $1),
SubtreeCreator.CreateMethodCall("bool", $3.source_context, $3),
$2.type, @$);
} }
| expr SLASHSLASH expr | expr SLASHSLASH expr
{ {
@ -542,9 +546,7 @@ expr
} }
| expr STARSTAR expr | expr STARSTAR expr
{ {
addressed_value method_name = new ident("!pow", @$); $$ = SubtreeCreator.CreateMethodCall("!pow", @$, $1, $3);
expression_list el = new expression_list(new List<expression> { $1, $3 }, @$);
$$ = new method_call(method_name, el, @$);
} }
| expr IN expr | expr IN expr
{ {
@ -561,7 +563,7 @@ expr
} }
| NOT expr | NOT expr
{ {
$$ = new un_expr($2, $1.type, @$); $$ = new un_expr(SubtreeCreator.CreateMethodCall("bool", $2.source_context, $2), $1.type, @$);
} }
| BINNOT expr | BINNOT expr
{ {
@ -817,12 +819,12 @@ variable
// list generator // list generator
| LBRACKET generator_object RBRACKET | LBRACKET generator_object RBRACKET
{ {
$$ = new method_call(new ident("list", $2.source_context), new expression_list($2, $2.source_context), $2.source_context); $$ = SubtreeCreator.CreateMethodCall("list", $2.source_context, $2);
} }
// set generator // set generator
| LBRACE generator_object RBRACE | LBRACE generator_object RBRACE
{ {
$$ = new method_call(new ident("set", $2.source_context), new expression_list($2, $2.source_context), $2.source_context); $$ = SubtreeCreator.CreateMethodCall("set", $2.source_context, $2);
} }
// dict generator // dict generator
| LBRACE generator_object_for_dict RBRACE | LBRACE generator_object_for_dict RBRACE
@ -862,11 +864,11 @@ generator_object_for_dict
dict_constant dict_constant
: LBRACE expr_mapping_list RBRACE : LBRACE expr_mapping_list RBRACE
{ {
$$ = new method_call(new ident("dict", @$), $2 as expression_list, @$); $$ = SubtreeCreator.CreateMethodCall("dict", @$, (expression_list)$2);
} }
| LBRACE RBRACE | LBRACE RBRACE
{ {
$$ = new method_call(new ident("!empty_dict", @$), null, @$); $$ = SubtreeCreator.CreateMethodCall("!empty_dict", @$);
} }
; ;
@ -874,7 +876,7 @@ set_constant
: LBRACE expr_list RBRACE : LBRACE expr_list RBRACE
{ {
var acn = new array_const_new($2 as expression_list, '|', @$); var acn = new array_const_new($2 as expression_list, '|', @$);
$$ = new method_call(new ident("set", @$), new expression_list(acn, @$), @$); $$ = SubtreeCreator.CreateMethodCall("set", @$, acn);
} }
; ;
@ -882,11 +884,11 @@ list_constant
: LBRACKET expr_list RBRACKET : LBRACKET expr_list RBRACKET
{ {
var acn = new array_const_new($2 as expression_list, '|', @$); var acn = new array_const_new($2 as expression_list, '|', @$);
$$ = new method_call(new ident("list", @$), new expression_list(acn, @$), @$); $$ = SubtreeCreator.CreateMethodCall("list", @$, acn);
} }
| LBRACKET RBRACKET | LBRACKET RBRACKET
{ {
$$ = new method_call(new ident("!empty_list", @$), null, @$); $$ = SubtreeCreator.CreateMethodCall("!empty_list", @$);
} }
; ;

View file

@ -4,7 +4,7 @@
// GPPG version 1.3.6 // GPPG version 1.3.6
// Machine: DESKTOP-V3E9T2U // Machine: DESKTOP-V3E9T2U
// DateTime: 15.12.2025 12:38:14 // DateTime: 29.01.2026 14:12:59
// UserName: alex // UserName: alex
// Input file <SPythonParser.y> // Input file <SPythonParser.y>
@ -1052,12 +1052,16 @@ public partial class SPythonGPPGParser: ShiftReduceParser<ValueType, LexLocation
break; break;
case 80: // expr -> expr, AND, expr case 80: // expr -> expr, AND, expr
{ {
CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); CurrentSemanticValue.ex = new bin_expr(SubtreeCreator.CreateMethodCall("bool", ValueStack[ValueStack.Depth-3].ex.source_context, ValueStack[ValueStack.Depth-3].ex),
SubtreeCreator.CreateMethodCall("bool", ValueStack[ValueStack.Depth-1].ex.source_context, ValueStack[ValueStack.Depth-1].ex),
ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan);
} }
break; break;
case 81: // expr -> expr, OR, expr case 81: // expr -> expr, OR, expr
{ {
CurrentSemanticValue.ex = new bin_expr(ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); CurrentSemanticValue.ex = new bin_expr(SubtreeCreator.CreateMethodCall("bool", ValueStack[ValueStack.Depth-3].ex.source_context, ValueStack[ValueStack.Depth-3].ex),
SubtreeCreator.CreateMethodCall("bool", ValueStack[ValueStack.Depth-1].ex.source_context, ValueStack[ValueStack.Depth-1].ex),
ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan);
} }
break; break;
case 82: // expr -> expr, SLASHSLASH, expr case 82: // expr -> expr, SLASHSLASH, expr
@ -1097,9 +1101,7 @@ public partial class SPythonGPPGParser: ShiftReduceParser<ValueType, LexLocation
break; break;
case 89: // expr -> expr, STARSTAR, expr case 89: // expr -> expr, STARSTAR, expr
{ {
addressed_value method_name = new ident("!pow", CurrentLocationSpan); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("!pow", CurrentLocationSpan, ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex);
expression_list el = new expression_list(new List<expression> { ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex }, CurrentLocationSpan);
CurrentSemanticValue.ex = new method_call(method_name, el, CurrentLocationSpan);
} }
break; break;
case 90: // expr -> expr, IN, expr case 90: // expr -> expr, IN, expr
@ -1120,7 +1122,7 @@ public partial class SPythonGPPGParser: ShiftReduceParser<ValueType, LexLocation
break; break;
case 93: // expr -> NOT, expr case 93: // expr -> NOT, expr
{ {
CurrentSemanticValue.ex = new un_expr(ValueStack[ValueStack.Depth-1].ex, ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan); CurrentSemanticValue.ex = new un_expr(SubtreeCreator.CreateMethodCall("bool", ValueStack[ValueStack.Depth-1].ex.source_context, ValueStack[ValueStack.Depth-1].ex), ValueStack[ValueStack.Depth-2].op.type, CurrentLocationSpan);
} }
break; break;
case 94: // expr -> BINNOT, expr case 94: // expr -> BINNOT, expr
@ -1361,12 +1363,12 @@ public partial class SPythonGPPGParser: ShiftReduceParser<ValueType, LexLocation
break; break;
case 138: // variable -> LBRACKET, generator_object, RBRACKET case 138: // variable -> LBRACKET, generator_object, RBRACKET
{ {
CurrentSemanticValue.ex = new method_call(new ident("list", ValueStack[ValueStack.Depth-2].ex.source_context), new expression_list(ValueStack[ValueStack.Depth-2].ex, ValueStack[ValueStack.Depth-2].ex.source_context), ValueStack[ValueStack.Depth-2].ex.source_context); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("list", ValueStack[ValueStack.Depth-2].ex.source_context, ValueStack[ValueStack.Depth-2].ex);
} }
break; break;
case 139: // variable -> LBRACE, generator_object, RBRACE case 139: // variable -> LBRACE, generator_object, RBRACE
{ {
CurrentSemanticValue.ex = new method_call(new ident("set", ValueStack[ValueStack.Depth-2].ex.source_context), new expression_list(ValueStack[ValueStack.Depth-2].ex, ValueStack[ValueStack.Depth-2].ex.source_context), ValueStack[ValueStack.Depth-2].ex.source_context); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("set", ValueStack[ValueStack.Depth-2].ex.source_context, ValueStack[ValueStack.Depth-2].ex);
} }
break; break;
case 140: // variable -> LBRACE, generator_object_for_dict, RBRACE case 140: // variable -> LBRACE, generator_object_for_dict, RBRACE
@ -1400,29 +1402,29 @@ public partial class SPythonGPPGParser: ShiftReduceParser<ValueType, LexLocation
break; break;
case 145: // dict_constant -> LBRACE, expr_mapping_list, RBRACE case 145: // dict_constant -> LBRACE, expr_mapping_list, RBRACE
{ {
CurrentSemanticValue.ex = new method_call(new ident("dict", CurrentLocationSpan), ValueStack[ValueStack.Depth-2].stn as expression_list, CurrentLocationSpan); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("dict", CurrentLocationSpan, (expression_list)ValueStack[ValueStack.Depth-2].stn);
} }
break; break;
case 146: // dict_constant -> LBRACE, RBRACE case 146: // dict_constant -> LBRACE, RBRACE
{ {
CurrentSemanticValue.ex = new method_call(new ident("!empty_dict", CurrentLocationSpan), null, CurrentLocationSpan); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("!empty_dict", CurrentLocationSpan);
} }
break; break;
case 147: // set_constant -> LBRACE, expr_list, RBRACE case 147: // set_constant -> LBRACE, expr_list, RBRACE
{ {
var acn = new array_const_new(ValueStack[ValueStack.Depth-2].stn as expression_list, '|', CurrentLocationSpan); var acn = new array_const_new(ValueStack[ValueStack.Depth-2].stn as expression_list, '|', CurrentLocationSpan);
CurrentSemanticValue.ex = new method_call(new ident("set", CurrentLocationSpan), new expression_list(acn, CurrentLocationSpan), CurrentLocationSpan); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("set", CurrentLocationSpan, acn);
} }
break; break;
case 148: // list_constant -> LBRACKET, expr_list, RBRACKET case 148: // list_constant -> LBRACKET, expr_list, RBRACKET
{ {
var acn = new array_const_new(ValueStack[ValueStack.Depth-2].stn as expression_list, '|', CurrentLocationSpan); var acn = new array_const_new(ValueStack[ValueStack.Depth-2].stn as expression_list, '|', CurrentLocationSpan);
CurrentSemanticValue.ex = new method_call(new ident("list", CurrentLocationSpan), new expression_list(acn, CurrentLocationSpan), CurrentLocationSpan); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("list", CurrentLocationSpan, acn);
} }
break; break;
case 149: // list_constant -> LBRACKET, RBRACKET case 149: // list_constant -> LBRACKET, RBRACKET
{ {
CurrentSemanticValue.ex = new method_call(new ident("!empty_list", CurrentLocationSpan), null, CurrentLocationSpan); CurrentSemanticValue.ex = SubtreeCreator.CreateMethodCall("!empty_list", CurrentLocationSpan);
} }
break; break;
case 150: // optional_condition -> /* empty */ case 150: // optional_condition -> /* empty */

View file

@ -1,12 +1,11 @@
using System.Collections.Generic; using PascalABCCompiler.Errors;
using PascalABCCompiler.SemanticTree; using PascalABCCompiler.SemanticTree;
using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.SystemLibrary; using PascalABCCompiler.SystemLibrary;
using PascalABCCompiler.TreeConverter; using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using PascalABCCompiler.Errors;
using System.ComponentModel.Design;
using System; using System;
using System.Collections.Generic;
namespace SPythonSyntaxTreeVisitor namespace SPythonSyntaxTreeVisitor
{ {
@ -27,6 +26,52 @@ namespace SPythonSyntaxTreeVisitor
OnLeave = RunAdditionalChecks; OnLeave = RunAdditionalChecks;
} }
type_intersection_node boolToIntIntersectionPrev;
type_intersection_node intToBoolIntersectionPrev;
public override void BeforeCompilationActions()
{
base.BeforeCompilationActions();
UpdateStandardTypes();
}
public override void PostCompilationActions()
{
base.PostCompilationActions();
RestoreStandardTypes();
}
private void UpdateStandardTypes()
{
// Неявное преобразование из int в bool и из bool в int
boolToIntIntersectionPrev = SystemLibrary.bool_type.remove_intersection_node(SystemLibrary.integer_type);
intToBoolIntersectionPrev = SystemLibrary.integer_type.remove_intersection_node(SystemLibrary.bool_type);
var newIntersection = new type_intersection_node(type_compare.less_type);
newIntersection.this_to_another = new type_conversion(new basic_function_node(basic_function_type.booltoi, SystemLibrary.integer_type, false), false);
newIntersection.another_to_this = new type_conversion(new basic_function_node(basic_function_type.itobool, SystemLibrary.bool_type, false), false);
SystemLibrary.bool_type.add_intersection_node(SystemLibrary.integer_type, newIntersection, false);
}
private void RestoreStandardTypes()
{
SystemLibrary.bool_type.remove_intersection_node(SystemLibrary.integer_type);
if (boolToIntIntersectionPrev != null)
SystemLibrary.bool_type.add_intersection_node(SystemLibrary.integer_type, boolToIntIntersectionPrev, false);
if (intToBoolIntersectionPrev != null)
SystemLibrary.integer_type.add_intersection_node(SystemLibrary.bool_type, intToBoolIntersectionPrev, false);
}
private void RunAdditionalChecks(syntax_tree_node node) private void RunAdditionalChecks(syntax_tree_node node)
{ {
switch (node) switch (node)

View file

@ -57,8 +57,12 @@ namespace PascalABCCompiler.TreeConverter
syntaxTreeVisitor.DirectivesToNodesLinks = CompilerDirectivesToSyntaxTreeNodesLinker.BuildLinks(initializationData.syntaxUnit, initializationData.errorsList); //MikhailoMMX добавил передачу списка ошибок (02.10.10) syntaxTreeVisitor.DirectivesToNodesLinks = CompilerDirectivesToSyntaxTreeNodesLinker.BuildLinks(initializationData.syntaxUnit, initializationData.errorsList); //MikhailoMMX добавил передачу списка ошибок (02.10.10)
syntaxTreeVisitor.BeforeCompilationActions();
syntaxTreeVisitor.ProcessNode(initializationData.syntaxUnit); syntaxTreeVisitor.ProcessNode(initializationData.syntaxUnit);
syntaxTreeVisitor.PostCompilationActions();
CompiledVariables.AddRange(syntaxTreeVisitor.CompiledVariables); CompiledVariables.AddRange(syntaxTreeVisitor.CompiledVariables);
return syntaxTreeVisitor.CompiledUnit; return syntaxTreeVisitor.CompiledUnit;
@ -75,9 +79,13 @@ namespace PascalABCCompiler.TreeConverter
foreach (SyntaxTree.compiler_directive cd in initializationData.syntaxUnit.compiler_directives) foreach (SyntaxTree.compiler_directive cd in initializationData.syntaxUnit.compiler_directives)
cd.visit(syntaxTreeVisitor); cd.visit(syntaxTreeVisitor);
syntaxTreeVisitor.visit_implementation(initializationData.syntaxUnit as SyntaxTree.unit_module); syntaxTreeVisitor.BeforeCompilationActions();
CompiledVariables.AddRange(syntaxTreeVisitor.CompiledVariables);
syntaxTreeVisitor.visit_implementation(initializationData.syntaxUnit as SyntaxTree.unit_module);
syntaxTreeVisitor.PostCompilationActions();
CompiledVariables.AddRange(syntaxTreeVisitor.CompiledVariables);
} }
public void Reset() public void Reset()

View file

@ -54,7 +54,7 @@ namespace PascalABCCompiler.SemanticTree
sbtos, sbtoi, sbtol, sbtof, sbtod, sbtob, sbtous, sbtoui, sbtoul, sbtochar,//signed byte to short, int, long, float, double sbtos, sbtoi, sbtol, sbtof, sbtod, sbtob, sbtous, sbtoui, sbtoul, sbtochar,//signed byte to short, int, long, float, double
stoi, stol, stof, stod, stob, stosb, stous, stoui, stoul, stochar, //short to ... stoi, stol, stof, stod, stob, stosb, stous, stoui, stoul, stochar, //short to ...
ustoi, ustoui, ustol, ustoul, ustof, ustod, ustob, ustosb, ustos, ustochar, //unsigned short to ... ustoi, ustoui, ustol, ustoul, ustof, ustod, ustob, ustosb, ustos, ustochar, //unsigned short to ...
itol, itof, itod, itob, itosb, itos, itous, itoui, itoul, itochar, //integer to ... itol, itof, itod, itob, itosb, itos, itous, itoui, itoul, itochar, itobool, //integer to ...
uitol, uitoul, uitob, uitosb, uitos, uitous, uitoi, uitof, uitod, uitochar, //uint to ... uitol, uitoul, uitob, uitosb, uitos, uitous, uitoi, uitof, uitod, uitochar, //uint to ...
ltof, ltod, ltob, ltosb, ltos, ltous, ltoi, ltoui, ltoul, ltochar, //long to ... ltof, ltod, ltob, ltosb, ltos, ltous, ltoi, ltoui, ltoul, ltochar, //long to ...
ultob, ultosb, ultos, ultous, ultoi, ultoui, ultol, ultochar, ultof, ultod, //ulong to ... ultob, ultosb, ultos, ultous, ultoi, ultoui, ultol, ultochar, ultof, ultod, //ulong to ...

View file

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
namespace PascalABCCompiler.SyntaxTree namespace PascalABCCompiler.SyntaxTree
{ {
@ -11,7 +10,7 @@ namespace PascalABCCompiler.SyntaxTree
/// <summary> /// <summary>
/// Класс для генерации новых узлов синтаксического дерева /// Класс для генерации новых узлов синтаксического дерева
/// </summary> /// </summary>
public class SyntaxTreeNodesConstructor public static class SyntaxTreeNodesConstructor
{ {
public static var_statement CreateVarStatementNode(string idName, type_definition varType, expression initValue) public static var_statement CreateVarStatementNode(string idName, type_definition varType, expression initValue)
{ {
@ -97,7 +96,7 @@ namespace PascalABCCompiler.SyntaxTree
} }
#endregion #endregion
public class SubtreeCreator public static class SubtreeCreator
{ {
/// <summary> /// <summary>
/// Создать var-выражение /// Создать var-выражение
@ -264,10 +263,10 @@ namespace PascalABCCompiler.SyntaxTree
/// <returns></returns> /// <returns></returns>
public static method_call CreateSystemFunctionCall(string funcName, params expression[] exprList) public static method_call CreateSystemFunctionCall(string funcName, params expression[] exprList)
{ {
return CreateMethodCall(funcName, "PABCSystem", exprList); return CreateMethodCallWithQualifier(funcName, "PABCSystem", exprList);
} }
public static method_call CreateMethodCall(string funcName, string qualifier, params expression[] exprList) public static method_call CreateMethodCallWithQualifier(string funcName, string qualifier, params expression[] exprList)
{ {
var methodCall = CreateMethodCall(funcName, exprList); var methodCall = CreateMethodCall(funcName, exprList);
methodCall.dereferencing_value = new dot_node(new ident(qualifier), new ident(funcName)); methodCall.dereferencing_value = new dot_node(new ident(qualifier), new ident(funcName));
@ -282,10 +281,27 @@ namespace PascalABCCompiler.SyntaxTree
} }
private static method_call CreateMethodCall(string methodName, params expression[] exprList) private static method_call CreateMethodCall(string methodName, params expression[] exprList)
{
return CreateMethodCall(methodName, null, exprList);
}
public static method_call CreateMethodCall(string methodName, SourceContext sc, expression_list expr_list)
{ {
SyntaxTree.method_call mc = new SyntaxTree.method_call(); SyntaxTree.method_call mc = new SyntaxTree.method_call();
mc.dereferencing_value = new ident(methodName); mc.source_context = sc;
mc.dereferencing_value = new ident(methodName, sc);
mc.parameters = expr_list;
return mc;
}
public static method_call CreateMethodCall(string methodName, SourceContext sc, params expression[] exprList)
{
SyntaxTree.method_call mc = new SyntaxTree.method_call();
mc.source_context = sc;
mc.dereferencing_value = new ident(methodName, sc);
SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list(); SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list();
exl.source_context = sc;
foreach (expression x in exprList) foreach (expression x in exprList)
exl.Add(x); exl.Add(x);
mc.parameters = exl; mc.parameters = exl;
@ -352,7 +368,7 @@ namespace PascalABCCompiler.SyntaxTree
return res; return res;
} }
} }
public class SyntaxTreeBuilder public static class SyntaxTreeBuilder
{ {
public static SourceContext BuildGenSC = new SourceContext(0, 777777, 0, 0, 0, 0); public static SourceContext BuildGenSC = new SourceContext(0, 777777, 0, 0, 0, 0);

View file

@ -625,7 +625,7 @@ namespace SyntaxVisitors.PatternsVisitors
} }
var deconstructCall = new procedure_call(); var deconstructCall = new procedure_call();
deconstructCall.func_name = SubtreeCreator.CreateMethodCall(DeconstructMethodName, castVariableName.name, parameters.Select(x => x.identifier).ToArray()); deconstructCall.func_name = SubtreeCreator.CreateMethodCallWithQualifier(DeconstructMethodName, castVariableName.name, parameters.Select(x => x.identifier).ToArray());
desugarResult.DeconstructCall = deconstructCall; desugarResult.DeconstructCall = deconstructCall;
return desugarResult; return desugarResult;

View file

@ -0,0 +1,16 @@
# int to bool and bool to int implicit conversion
a: int = True
b: bool = 5
if 10:
print((1 > 0) + 1)
while 0:
print('Infinite loop')
print(bool(1))
print(filter(bool, [0, 1, 2]))
print(all([0, 1, 3]))
print(sum([True, False, True]))

View file

@ -171,6 +171,16 @@ namespace PascalABCCompiler.TreeConverter
context.syntax_tree_visitor = this; context.syntax_tree_visitor = this;
} }
/// <summary>
/// Можно переопределять для добавления действий перед конвертацией интерфейсной и имплементационной частей
/// </summary>
public virtual void BeforeCompilationActions() { }
/// <summary>
/// Можно переопределять для добавления действий после конвертации интерфейсной и имплементационной частей
/// </summary>
public virtual void PostCompilationActions() { }
public List<TreeRealization.var_definition_node> CompiledVariables => compiledVariables; public List<TreeRealization.var_definition_node> CompiledVariables => compiledVariables;
public string UniqueNumStr() public string UniqueNumStr()

View file

@ -317,6 +317,26 @@ namespace PascalABCCompiler.TreeRealization
generated_type_intersections.Add(tn); generated_type_intersections.Add(tn);
} }
} }
/// <summary>
/// Удаляет узел пересечения текущего типа и типа tn.
/// Возвращает удаленный узел (или null).
/// </summary>
public type_intersection_node remove_intersection_node(type_node tn, bool is_generated = false)
{
var intersection = get_type_intersection(tn);
if (intersection != null)
{
type_intersections.Remove(tn);
if (is_generated)
generated_type_intersections.Remove(tn);
}
return intersection;
}
public void clear_generated_intersections() public void clear_generated_intersections()
{ {
if (generated_type_intersections == null || type_intersections == null) if (generated_type_intersections == null || type_intersections == null)

View file

@ -44,7 +44,9 @@ type kwargs_gen<T> = class
end; end;
function all(s: sequence of boolean): boolean; function all(s: sequence of boolean): boolean;
function all(s: sequence of integer): boolean;
function any(s: sequence of boolean): boolean; function any(s: sequence of boolean): boolean;
function any(s: sequence of integer): boolean;
function enumerate<T>(s: sequence of T; start: integer := 0): sequence of (integer,T); function enumerate<T>(s: sequence of T; start: integer := 0): sequence of (integer,T);
function filter<T>(cond: T -> boolean; s: sequence of T): sequence of T; function filter<T>(cond: T -> boolean; s: sequence of T): sequence of T;
@ -55,6 +57,16 @@ function int(val: string): integer;
function int(val: real): integer; function int(val: real): integer;
function int(b: boolean): integer;
function str(val: object): string;
function float(val: string): real;
function float(x: integer): real;
function bool(val: integer): boolean;
function round(val: real): integer; function round(val: real): integer;
function split(s: string): sequence of string; function split(s: string): sequence of string;
@ -64,15 +76,6 @@ function get_values<K, V>(dct: Dictionary<K, V>): sequence of V;
function &type(obj: object): string; function &type(obj: object): string;
//function int(val: string): integer;
function int(b: boolean): integer;
function str(val: object): string;
function float(val: string): real;
function float(x: integer): real;
// Basic sequence functions // Basic sequence functions
function range(s: integer; e: integer; step: integer): sequence of integer; function range(s: integer; e: integer; step: integer): sequence of integer;
@ -87,10 +90,6 @@ function !format(i: integer; fmt: string): string;
function !format(val: real; fmt: string): string; function !format(val: real; fmt: string): string;
//function all<T>(seq: sequence of T): boolean;
//function any<T>(seq: sequence of T): boolean;
//------------------------------------ //------------------------------------
// Standard Math functions // Standard Math functions
//------------------------------------ //------------------------------------
@ -110,7 +109,7 @@ function pow(x: real; n: integer): real;
/// Возвращает x в целой степени n /// Возвращает x в целой степени n
function pow(x: BigInteger; n: integer): BigInteger; function pow(x: BigInteger; n: integer): BigInteger;
// function floor(x: real): real; {$region STANDARD CONTAINERS}
type list<T> = class(IEnumerable<T>) type list<T> = class(IEnumerable<T>)
private private
@ -490,6 +489,8 @@ type dict<K, V> = class(IEnumerable<PABCSystem.KeyValuePair<K, V>>)
function System.Collections.IEnumerable.GetEnumerator() : System.Collections.IEnumerator := GetEnumerator(); function System.Collections.IEnumerable.GetEnumerator() : System.Collections.IEnumerator := GetEnumerator();
end; end;
{$endregion STANDARD CONTAINERS}
//Standard functions with Lists //Standard functions with Lists
function len<T>(lst: list<T>): integer; function len<T>(lst: list<T>): integer;
@ -498,13 +499,11 @@ function len<K, V>(dct: dict<K, V>): integer;
function len<T>(arr: array of T): integer; function len<T>(arr: array of T): integer;
function len(s: string): integer; function len(s: string): integer;
// function &set<T>(sq: sequence of T): &set<T>;
function sorted<T>(lst: list<T>): list<T>; function sorted<T>(lst: list<T>): list<T>;
function sum(lst: sequence of integer): integer; function sum(s: sequence of boolean): integer;
function sum(s: sequence of integer): integer;
function sum(lst: sequence of real): real; function sum(s: sequence of real): real;
function !assign<T>(var a: T; b: T): T; function !assign<T>(var a: T; b: T): T;
@ -645,6 +644,8 @@ function float(val: string): real := real.Parse(val);
function float(x: integer): real := PABCSystem.Floor(x); function float(x: integer): real := PABCSystem.Floor(x);
function bool(val: integer): boolean := Convert.ToBoolean(val);
function range(s: integer; e: integer; step: integer): sequence of integer; function range(s: integer; e: integer; step: integer): sequence of integer;
begin begin
Result := PABCSystem.Range(s, e - PABCSystem.Sign(step), step); Result := PABCSystem.Range(s, e - PABCSystem.Sign(step), step);
@ -660,10 +661,6 @@ begin
Result := PABCSystem.Range(0, e - 1); Result := PABCSystem.Range(0, e - 1);
end; end;
//function all<T>(seq: sequence of T): boolean := seq.All(x -> x);
//function any<T>(seq: sequence of T): boolean := seq.Any(x -> x);
//------------------------------------ //------------------------------------
// Standard Math functions // Standard Math functions
//------------------------------------ //------------------------------------
@ -694,8 +691,9 @@ begin
Result := newList; Result := newList;
end; end;
function sum(lst: sequence of integer): integer := lst.sum(); function sum(s: sequence of boolean): integer := s.Select(x -> Convert.ToInt32(x)).Sum();
function sum(lst: sequence of real): real := lst.sum(); function sum(s: sequence of integer): integer := s.Sum();
function sum(s: sequence of real): real := s.Sum();
function !assign<T>(var a: T; b: T): T; function !assign<T>(var a: T; b: T): T;
begin begin
@ -811,11 +809,6 @@ function CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
// TUPLES END // TUPLES END
//function &set<T>(sq: sequence of T): &set<T>;
//begin
// Result := new &set<T>(sq);
//end;
function all(s: sequence of boolean): boolean; function all(s: sequence of boolean): boolean;
begin begin
Result := true; Result := true;
@ -827,6 +820,8 @@ begin
end; end;
end; end;
function all(s: sequence of integer): boolean := all(s.Select(x -> Convert.ToBoolean(x)));
function any(s: sequence of boolean): boolean; function any(s: sequence of boolean): boolean;
begin begin
Result := false; Result := false;
@ -838,6 +833,8 @@ begin
end; end;
end; end;
function any(s: sequence of integer): boolean := any(s.Select(x -> Convert.ToBoolean(x)));
///- ///-
function ToDictionary<T, U>(Self: sequence of System.Tuple<T, U>): dict<T, U>; extensionmethod; function ToDictionary<T, U>(Self: sequence of System.Tuple<T, U>): dict<T, U>; extensionmethod;
begin begin