Исправление div (//) и mod (%) для SPython (#3384)
* Fix div and mod in SPython * Fix generic type names search in SPython symbol table * Small fixes * Add few checks in Intellisense * Add comments about units compilation order
This commit is contained in:
parent
9606f1ece4
commit
b8bda89f0f
|
|
@ -62,11 +62,13 @@
|
||||||
%left SHL SHR
|
%left SHL SHR
|
||||||
%left PLUS MINUS
|
%left PLUS MINUS
|
||||||
%left STAR DIVIDE SLASHSLASH PERCENTAGE
|
%left STAR DIVIDE SLASHSLASH PERCENTAGE
|
||||||
%right STARSTAR
|
%right UMINUS UPLUS
|
||||||
%left BINNOT
|
%left BINNOT
|
||||||
|
%right STARSTAR
|
||||||
|
|
||||||
|
|
||||||
%type <id> ident func_name_ident type_decl_identifier
|
%type <id> ident func_name_ident type_decl_identifier
|
||||||
%type <ex> extended_expr expr dotted_ident proc_func_call const_value variable optional_condition act_param extended_new_expr new_expr is_expr variable_as_type
|
%type <ex> extended_expr expr dotted_ident proc_func_call const_value variable optional_condition act_param new_expr is_expr variable_as_type
|
||||||
%type <stn> act_param_list optional_act_param_list proc_func_decl return_stmt break_stmt continue_stmt global_stmt pass_stmt
|
%type <stn> act_param_list optional_act_param_list proc_func_decl return_stmt break_stmt continue_stmt global_stmt pass_stmt
|
||||||
%type <stn> var_stmt assign_stmt if_stmt stmt proc_func_call_stmt while_stmt for_stmt optional_else optional_elif exit_stmt
|
%type <stn> var_stmt assign_stmt if_stmt stmt proc_func_call_stmt while_stmt for_stmt optional_else optional_elif exit_stmt
|
||||||
%type <stn> expr_list
|
%type <stn> expr_list
|
||||||
|
|
@ -145,23 +147,14 @@ extended_expr
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| extended_new_expr
|
// вызов конструктора без скобочек
|
||||||
{
|
|
||||||
$$ = $1;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
extended_new_expr
|
|
||||||
: new_expr
|
|
||||||
{
|
|
||||||
$$ = $1;
|
|
||||||
}
|
|
||||||
| NEW type_ref
|
| NEW type_ref
|
||||||
{
|
{
|
||||||
$$ = new new_expr($2, null, false, null, @$);
|
$$ = new new_expr($2, null, false, null, @$);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
type_decl_identifier
|
type_decl_identifier
|
||||||
: ident
|
: ident
|
||||||
{
|
{
|
||||||
|
|
@ -557,7 +550,11 @@ expr
|
||||||
// $$ = new bin_expr($1, $4, Operators.NotIn, @$);
|
// $$ = new bin_expr($1, $4, Operators.NotIn, @$);
|
||||||
$$ = new un_expr(new bin_expr($1, $4, Operators.In, @$),Operators.LogicalNOT,@$);
|
$$ = new un_expr(new bin_expr($1, $4, Operators.In, @$),Operators.LogicalNOT,@$);
|
||||||
}
|
}
|
||||||
| MINUS expr
|
| PLUS expr %prec UPLUS
|
||||||
|
{
|
||||||
|
$$ = new un_expr($2, $1.type, @$);
|
||||||
|
}
|
||||||
|
| MINUS expr %prec UMINUS
|
||||||
{
|
{
|
||||||
$$ = new un_expr($2, $1.type, @$);
|
$$ = new un_expr($2, $1.type, @$);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
||||||
cls
|
cls
|
||||||
..\..\..\Utils\GPLex_GPPG\Gplex.exe /unicode SPythonLexer.lex
|
..\..\..\Utils\GPLex_GPPG\Gplex.exe /unicode SPythonLexer.lex
|
||||||
..\..\..\Utils\GPLex_GPPG\Gppg.exe /no-lines /gplex SPythonParser.y
|
..\..\..\Utils\GPLex_GPPG\Gppg.exe /verbose /no-lines /gplex SPythonParser.y
|
||||||
pause
|
pause
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using PascalABCCompiler.Errors;
|
using PascalABCCompiler;
|
||||||
|
using PascalABCCompiler.Errors;
|
||||||
using PascalABCCompiler.SemanticTree;
|
using PascalABCCompiler.SemanticTree;
|
||||||
using PascalABCCompiler.SyntaxTree;
|
using PascalABCCompiler.SyntaxTree;
|
||||||
using PascalABCCompiler.SystemLibrary;
|
using PascalABCCompiler.SystemLibrary;
|
||||||
|
|
@ -6,6 +7,8 @@ using PascalABCCompiler.TreeConverter;
|
||||||
using PascalABCCompiler.TreeRealization;
|
using PascalABCCompiler.TreeRealization;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using static PascalABCCompiler.StringConstants;
|
||||||
|
|
||||||
namespace SPythonSyntaxTreeVisitor
|
namespace SPythonSyntaxTreeVisitor
|
||||||
{
|
{
|
||||||
|
|
@ -241,7 +244,7 @@ namespace SPythonSyntaxTreeVisitor
|
||||||
}
|
}
|
||||||
break;*/
|
break;*/
|
||||||
case Operators.Division:
|
case Operators.Division:
|
||||||
if (left.type == right.type && left.type.name == "string")
|
if (left.type == right.type && left.type.name == string_type_name)
|
||||||
{
|
{
|
||||||
var mcn = new method_call(new dot_node(new semantic_addr_value(left, left.location), new ident("IndexOf")),
|
var mcn = new method_call(new dot_node(new semantic_addr_value(left, left.location), new ident("IndexOf")),
|
||||||
new expression_list(new semantic_addr_value(right, right.location)), _bin_expr.source_context);
|
new expression_list(new semantic_addr_value(right, right.location)), _bin_expr.source_context);
|
||||||
|
|
@ -250,26 +253,37 @@ namespace SPythonSyntaxTreeVisitor
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Operators.IntegerDivision:
|
case Operators.IntegerDivision:
|
||||||
if (left.type == right.type && left.type.name == "real")
|
|
||||||
|
var possibleTypes = new string[] { integer_type_name, real_type_name, biginteger_type_name };
|
||||||
|
|
||||||
|
var possibleCombinations = possibleTypes.SelectMany(t => possibleTypes, (t1, t2) => Tuple.Create(t1, t2))
|
||||||
|
.Where(tt => !tt.Equals(Tuple.Create(real_type_name, biginteger_type_name))
|
||||||
|
&& !tt.Equals(Tuple.Create(biginteger_type_name, real_type_name)));
|
||||||
|
|
||||||
|
if (possibleCombinations.Contains(Tuple.Create(left.type.name, right.type.name)))
|
||||||
{
|
{
|
||||||
var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context;
|
var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context;
|
||||||
exprlist.Add(new semantic_addr_value(left, left.location));
|
exprlist.Add(new semantic_addr_value(left, left.location));
|
||||||
exprlist.Add(new semantic_addr_value(right, right.location));
|
exprlist.Add(new semantic_addr_value(right, right.location));
|
||||||
var floornode = new method_call(new ident("!FloorDiv"), exprlist, _bin_expr.source_context);
|
var floornode = new method_call(new ident("!Div"), exprlist, _bin_expr.source_context);
|
||||||
visit(floornode);
|
visit(floornode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Operators.ModulusRemainder:
|
case Operators.ModulusRemainder:
|
||||||
if (left.type == right.type && left.type.name == "real")
|
|
||||||
|
possibleTypes = new string[] { integer_type_name, real_type_name, biginteger_type_name };
|
||||||
|
|
||||||
|
possibleCombinations = possibleTypes.SelectMany(t => possibleTypes, (t1, t2) => Tuple.Create(t1, t2))
|
||||||
|
.Where(tt => !tt.Equals(Tuple.Create(real_type_name, biginteger_type_name))
|
||||||
|
&& !tt.Equals(Tuple.Create(biginteger_type_name, real_type_name)));
|
||||||
|
|
||||||
|
if (possibleCombinations.Contains(Tuple.Create(left.type.name, right.type.name)))
|
||||||
{
|
{
|
||||||
//var divnode = new bin_expr(new semantic_addr_value(left, left.location), new semantic_addr_value(right, right.location), Operators.IntegerDivision, _bin_expr.source_context);
|
|
||||||
//var multnode = new bin_expr(new semantic_addr_value(right, right.location), divnode, Operators.Multiplication);
|
|
||||||
//var modnode = new bin_expr(new semantic_addr_value(left, left.location), multnode, Operators.Minus);
|
|
||||||
var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context;
|
var exprlist = new expression_list(); exprlist.source_context = _bin_expr.source_context;
|
||||||
exprlist.Add(new semantic_addr_value(left, left.location));
|
exprlist.Add(new semantic_addr_value(left, left.location));
|
||||||
exprlist.Add(new semantic_addr_value(right, right.location));
|
exprlist.Add(new semantic_addr_value(right, right.location));
|
||||||
var modnode = new method_call(new ident("!FloorMod"), exprlist, _bin_expr.source_context);
|
var modnode = new method_call(new ident("!Mod"), exprlist, _bin_expr.source_context);
|
||||||
visit(modnode);
|
visit(modnode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
|
|
||||||
public override void visit(tuple_node tup)
|
public override void visit(tuple_node tup)
|
||||||
{
|
{
|
||||||
var dn = new ident("CreateTuple", tup.source_context);
|
var dn = new ident("!CreateTuple", tup.source_context);
|
||||||
var mc = new method_call(dn, tup.el, tup.source_context);
|
var mc = new method_call(dn, tup.el, tup.source_context);
|
||||||
|
|
||||||
//var sug = new sugared_expression(tup, mc, tup.source_context); - нет никакой семантической проверки - всё - на уровне синтаксиса!
|
//var sug = new sugared_expression(tup, mc, tup.source_context); - нет никакой семантической проверки - всё - на уровне синтаксиса!
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
{
|
{
|
||||||
public HashSet<string> variablesUsedAsGlobal = new HashSet<string>();
|
public HashSet<string> variablesUsedAsGlobal = new HashSet<string>();
|
||||||
|
|
||||||
public NameCorrectVisitor(Dictionary<string, Dictionary<string, bool>> namesFromUsedUnits, HashSet<string> definedFunctionsNames) : base(namesFromUsedUnits)
|
public NameCorrectVisitor(string unitName, Dictionary<string, Dictionary<string, bool>> namesFromUsedUnits, HashSet<string> definedFunctionsNames) : base(unitName, namesFromUsedUnits)
|
||||||
{
|
{
|
||||||
foreach (string definedFunctionName in definedFunctionsNames)
|
foreach (string definedFunctionName in definedFunctionsNames)
|
||||||
{
|
{
|
||||||
|
|
@ -104,22 +104,31 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// функция нужна для классов list, dict и set из-за наличия одноименных функций в другом модуле
|
||||||
public override void visit(template_type_reference _template_type_reference)
|
public override void visit(template_type_reference _template_type_reference)
|
||||||
{
|
{
|
||||||
named_type_reference _named_type_reference = _template_type_reference.name;
|
named_type_reference _named_type_reference = _template_type_reference.name;
|
||||||
string name = _named_type_reference.names[0].name;
|
string name = _named_type_reference.names[0].name + '`';
|
||||||
|
|
||||||
string fullName = name + $"`{_template_type_reference.params_list.Count}";
|
NameKind nameKind = symbolTable[name];
|
||||||
|
|
||||||
NameKind nameKind = symbolTable[fullName];
|
// синонимы типов без '`'
|
||||||
|
if (nameKind == NameKind.Unknown)
|
||||||
|
{
|
||||||
|
name = name.TrimEnd('`');
|
||||||
|
nameKind = symbolTable[name];
|
||||||
|
}
|
||||||
|
|
||||||
switch (nameKind)
|
switch (nameKind)
|
||||||
{
|
{
|
||||||
|
case NameKind.ModuleAlias:
|
||||||
|
_named_type_reference.names[0].name = symbolTable.AliasToRealName(name);
|
||||||
|
break;
|
||||||
|
|
||||||
case NameKind.ImportedVariableAlias:
|
case NameKind.ImportedVariableAlias:
|
||||||
case NameKind.ImportedNotVariableAlias:
|
case NameKind.ImportedNotVariableAlias:
|
||||||
_named_type_reference.names.Insert(0, new ident(symbolTable.AliasToModuleName(fullName), _named_type_reference.names[0].source_context));
|
_named_type_reference.names.Insert(0, new ident(symbolTable.AliasToModuleName(name), _named_type_reference.names[0].source_context));
|
||||||
_named_type_reference.names[1].name = symbolTable.AliasToRealName(fullName);
|
_named_type_reference.names[1].name = symbolTable.AliasToRealName(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NameKind.Unknown:
|
case NameKind.Unknown:
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,8 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
|
|
||||||
// проверка корректности имён, разрешение неоднозначности
|
// проверка корректности имён, разрешение неоднозначности
|
||||||
// сохранение множества переменных, использующихся как глобальные в ncv.variablesUsedAsGlobal
|
// сохранение множества переменных, использующихся как глобальные в ncv.variablesUsedAsGlobal
|
||||||
var ncv = new NameCorrectVisitor(compilationArtifacts.NamesFromUsedUnits, ffv.definedFunctionsNames);
|
var ncv = new NameCorrectVisitor(System.IO.Path.GetFileNameWithoutExtension(((compilation_unit)root).file_name),
|
||||||
|
compilationArtifacts.NamesFromUsedUnits, ffv.definedFunctionsNames);
|
||||||
|
|
||||||
if (!new TryCatchDecorator(ncv, forIntellisense).ProcessNode(root))
|
if (!new TryCatchDecorator(ncv, forIntellisense).ProcessNode(root))
|
||||||
return root;
|
return root;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using PascalABCCompiler.Parsers;
|
||||||
using PascalABCCompiler.SyntaxTree;
|
using PascalABCCompiler.SyntaxTree;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Languages.SPython.Frontend.Converters
|
namespace Languages.SPython.Frontend.Converters
|
||||||
{
|
{
|
||||||
|
|
@ -13,8 +14,8 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
|
|
||||||
private readonly ILanguageInformation languageInformation = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").LanguageInformation;
|
private readonly ILanguageInformation languageInformation = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").LanguageInformation;
|
||||||
|
|
||||||
public SymbolTableFillingVisitor(Dictionary<string, Dictionary<string, bool>> par) {
|
public SymbolTableFillingVisitor(string unitName, Dictionary<string, Dictionary<string, bool>> par) {
|
||||||
symbolTable = new SymbolTable(par);
|
symbolTable = new SymbolTable(unitName, par);
|
||||||
}
|
}
|
||||||
|
|
||||||
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
|
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
|
||||||
|
|
@ -176,11 +177,15 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
{
|
{
|
||||||
var namesDict = symbolTable.ModuleNameToSymbols[module_name];
|
var namesDict = symbolTable.ModuleNameToSymbols[module_name];
|
||||||
|
|
||||||
if (!namesDict.ContainsKey(as_Statement.real_name.name))
|
// Учитываем, что в именах может быть обозначение шаблонности
|
||||||
|
var foundName = namesDict.FirstOrDefault(kv => !kv.Key.Contains('`') && kv.Key == as_Statement.real_name.name
|
||||||
|
|| kv.Key.Contains('`') && kv.Key.Substring(0, kv.Key.IndexOf('`')) == as_Statement.real_name.name).Key;
|
||||||
|
|
||||||
|
if (foundName == null)
|
||||||
throw new SPythonSyntaxVisitorError("MODULE_{0}_HAS_NO_NAME_{1}",
|
throw new SPythonSyntaxVisitorError("MODULE_{0}_HAS_NO_NAME_{1}",
|
||||||
_from_import_statement.source_context, module_real_name, as_Statement.real_name.name);
|
_from_import_statement.source_context, module_real_name, as_Statement.real_name.name);
|
||||||
|
|
||||||
symbolTable.AddAlias(as_Statement.real_name.name, namesDict[as_Statement.real_name.name], as_Statement.alias.name, module_name);
|
symbolTable.AddAlias(as_Statement.real_name.name, namesDict[foundName], as_Statement.alias.name, module_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +231,7 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
private readonly HashSet<string> forwardDeclaredFunctions = new HashSet<string>();
|
private readonly HashSet<string> forwardDeclaredFunctions = new HashSet<string>();
|
||||||
|
|
||||||
private readonly string[] Keywords = {
|
private readonly string[] Keywords = {
|
||||||
"int", "float", "str", "bool", "tuple", // standard types
|
"int", "float", "str", "bool", "bigint", // standard types
|
||||||
"break", "continue", "exit", "halt", // standard ops
|
"break", "continue", "exit", "halt", // standard ops
|
||||||
"true", "false", // constants
|
"true", "false", // constants
|
||||||
};
|
};
|
||||||
|
|
@ -237,12 +242,14 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
currentScope.Add(keyword, NameKind.Keyword);
|
currentScope.Add(keyword, NameKind.Keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SymbolTable(Dictionary<string, Dictionary<string, bool>> par)
|
public SymbolTable(string unitName, Dictionary<string, Dictionary<string, bool>> par)
|
||||||
{
|
{
|
||||||
ModuleNameToSymbols = par;
|
ModuleNameToSymbols = par;
|
||||||
entryScope = new LocalScope();
|
entryScope = new LocalScope();
|
||||||
currentScope = entryScope;
|
currentScope = entryScope;
|
||||||
FillKeywords();
|
FillKeywords();
|
||||||
|
|
||||||
|
if (!StandardLibraries.Contains(unitName))
|
||||||
AddAliasesFromStandartLibraries();
|
AddAliasesFromStandartLibraries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,6 +354,17 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
|
|
||||||
public void AddAlias(string realName, bool isVariable, string alias, string moduleName)
|
public void AddAlias(string realName, bool isVariable, string alias, string moduleName)
|
||||||
{
|
{
|
||||||
|
// оставляем только обозначение шаблонности
|
||||||
|
if (alias.Contains("`"))
|
||||||
|
{
|
||||||
|
alias = alias.Substring(0, alias.IndexOf('`') + 1);
|
||||||
|
}
|
||||||
|
// в realName не должно быть обозначения шаблонности, потому что оно пойдет в синтаксический узел
|
||||||
|
if (realName.Contains("`"))
|
||||||
|
{
|
||||||
|
realName = realName.Substring(0, realName.IndexOf('`'));
|
||||||
|
}
|
||||||
|
|
||||||
entryScope.Add(alias, realName, isVariable ? NameKind.ImportedVariableAlias : NameKind.ImportedNotVariableAlias, moduleName);
|
entryScope.Add(alias, realName, isVariable ? NameKind.ImportedVariableAlias : NameKind.ImportedNotVariableAlias, moduleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Languages.SPython.Frontend.Converters
|
||||||
throw new SPythonSyntaxVisitorError("LONG_TUPLE_TYPENAME",
|
throw new SPythonSyntaxVisitorError("LONG_TUPLE_TYPENAME",
|
||||||
ttr.source_context, cnt);
|
ttr.source_context, cnt);
|
||||||
}
|
}
|
||||||
ttr.name.names[index].name += cnt;
|
ttr.name.names[index].name = "!tuple" + cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.visit(ttr);
|
base.visit(ttr);
|
||||||
|
|
|
||||||
|
|
@ -2692,13 +2692,17 @@ namespace CodeCompletion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Далее импортирумые пользовательские модули компилируются в обратном порядке, стандартные модули в порядке описания
|
||||||
|
|
||||||
List<string> usedUnitsNames = new List<string>();
|
List<string> usedUnitsNames = new List<string>();
|
||||||
|
|
||||||
interface_node _interface_node = _unit_module.interface_part;
|
interface_node _interface_node = _unit_module.interface_part;
|
||||||
|
|
||||||
if (_interface_node.uses_modules != null)
|
if (_interface_node.uses_modules != null)
|
||||||
{
|
{
|
||||||
usedUnitsNames = _interface_node.uses_modules.units.Select(unit => unit.name.idents[0].name).ToList();
|
usedUnitsNames = _interface_node.uses_modules.units
|
||||||
|
.Where(unit => unit.name.idents.Count == 1)
|
||||||
|
.Select(unit => unit.name.idents[0].name).ToList();
|
||||||
|
|
||||||
(cur_scope as InterfaceUnitScope).uses_source_range = get_location(_interface_node.uses_modules);
|
(cur_scope as InterfaceUnitScope).uses_source_range = get_location(_interface_node.uses_modules);
|
||||||
|
|
||||||
|
|
@ -2714,7 +2718,7 @@ namespace CodeCompletion
|
||||||
// компиляция зависимостей из конструкций import и from import
|
// компиляция зависимостей из конструкций import и from import
|
||||||
if (cur_scope != null && _unit_module.initialization_part != null)
|
if (cur_scope != null && _unit_module.initialization_part != null)
|
||||||
{
|
{
|
||||||
CompileImportedDependencies(_unit_module.initialization_part, _unit_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage);
|
CompileImportedDependencies(_unit_module.initialization_part, cur_scope, _unit_module.file_name, ns_cache, currentUnitLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
|
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
|
||||||
|
|
@ -3046,6 +3050,8 @@ namespace CodeCompletion
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var comparer = currentUnitLanguage.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
|
||||||
|
|
||||||
// на случай имен модулей, отличающихся от имен файла EVA
|
// на случай имен модулей, отличающихся от имен файла EVA
|
||||||
string realName = GetRealNameForModule(importedName);
|
string realName = GetRealNameForModule(importedName);
|
||||||
|
|
||||||
|
|
@ -3060,7 +3066,7 @@ namespace CodeCompletion
|
||||||
if (dc.visitor != null)
|
if (dc.visitor != null)
|
||||||
{
|
{
|
||||||
dc.visitor.entry_scope.InitAssemblies();
|
dc.visitor.entry_scope.InitAssemblies();
|
||||||
AddImportedNamesToCurScope(importStatement, asStatementsList, cur_scope, importedName, dc.visitor.entry_scope);
|
AddImportedNamesToCurScope(importStatement, asStatementsList, cur_scope, importedName, dc.visitor.entry_scope, comparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -3072,7 +3078,7 @@ namespace CodeCompletion
|
||||||
IntellisensePCUReader pcu_rdr = new IntellisensePCUReader();
|
IntellisensePCUReader pcu_rdr = new IntellisensePCUReader();
|
||||||
SymScope ss = pcu_rdr.GetUnit(unit_name);
|
SymScope ss = pcu_rdr.GetUnit(unit_name);
|
||||||
UnitDocCache.Load(ss, unit_name);
|
UnitDocCache.Load(ss, unit_name);
|
||||||
AddImportedNamesToCurScope(importStatement, asStatementsList, cur_scope, importedName, ss);
|
AddImportedNamesToCurScope(importStatement, asStatementsList, cur_scope, importedName, ss, comparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3086,17 +3092,17 @@ namespace CodeCompletion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddImportedNamesToCurScope(statement importStatement, as_statement_list asStatementsList, SymScope currentScope, string importedModuleName, SymScope importedModuleScope)
|
private static void AddImportedNamesToCurScope(statement importStatement, as_statement_list asStatementsList, SymScope currentScope, string importedModuleName, SymScope importedModuleScope, StringComparison comparer)
|
||||||
{
|
{
|
||||||
int fictiveUnitIndex = currentScope.used_units.FindIndex(unit => unit.Name == importedModuleName);
|
if (importStatement is import_statement import)
|
||||||
|
{
|
||||||
|
int fictiveUnitIndex = currentScope.used_units.FindIndex(unit => unit.Name.Equals(importedModuleName + "?ModuleName", comparer));
|
||||||
|
|
||||||
SymScope fictiveUnit = fictiveUnitIndex > -1 ? currentScope.used_units[fictiveUnitIndex] : null;
|
SymScope fictiveUnit = fictiveUnitIndex > -1 ? currentScope.used_units[fictiveUnitIndex] : null;
|
||||||
|
|
||||||
if (importStatement is import_statement import)
|
|
||||||
{
|
|
||||||
if (fictiveUnit == null)
|
if (fictiveUnit == null)
|
||||||
{
|
{
|
||||||
fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName, SymbolKind.Namespace, ""), null);
|
fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName + "?ModuleName", SymbolKind.Namespace, ""), null);
|
||||||
currentScope.AddUsedUnit(fictiveUnit);
|
currentScope.AddUsedUnit(fictiveUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3112,6 +3118,10 @@ namespace CodeCompletion
|
||||||
}
|
}
|
||||||
else if (importStatement is from_import_statement fromImport)
|
else if (importStatement is from_import_statement fromImport)
|
||||||
{
|
{
|
||||||
|
int fictiveUnitIndex = currentScope.used_units.FindIndex(unit => unit.Name.Equals(importedModuleName, comparer));
|
||||||
|
|
||||||
|
SymScope fictiveUnit = fictiveUnitIndex > -1 ? currentScope.used_units[fictiveUnitIndex] : null;
|
||||||
|
|
||||||
if (fromImport.is_star)
|
if (fromImport.is_star)
|
||||||
{
|
{
|
||||||
if (fictiveUnit != null)
|
if (fictiveUnit != null)
|
||||||
|
|
@ -3270,11 +3280,15 @@ namespace CodeCompletion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Далее импортирумые пользовательские модули компилируются в обратном порядке, стандартные модули в порядке описания
|
||||||
|
|
||||||
List<string> usedUnitsNames = new List<string>();
|
List<string> usedUnitsNames = new List<string>();
|
||||||
|
|
||||||
if (_program_module.used_units != null)
|
if (_program_module.used_units != null)
|
||||||
{
|
{
|
||||||
usedUnitsNames = _program_module.used_units.units.Select(unit => unit.name.idents[0].name).ToList();
|
usedUnitsNames = _program_module.used_units.units
|
||||||
|
.Where(unit => unit.name.idents.Count == 1)
|
||||||
|
.Select(unit => unit.name.idents[0].name).ToList();
|
||||||
|
|
||||||
unit_scope.uses_source_range = get_location(_program_module.used_units);
|
unit_scope.uses_source_range = get_location(_program_module.used_units);
|
||||||
|
|
||||||
|
|
@ -3290,7 +3304,7 @@ namespace CodeCompletion
|
||||||
// компиляция зависимостей из конструкций import и from import
|
// компиляция зависимостей из конструкций import и from import
|
||||||
if (cur_scope != null && _program_module.program_block.program_code != null)
|
if (cur_scope != null && _program_module.program_block.program_code != null)
|
||||||
{
|
{
|
||||||
CompileImportedDependencies(_program_module.program_block.program_code, _program_module.file_name, ns_cache, usedUnitsNames, currentUnitLanguage);
|
CompileImportedDependencies(_program_module.program_block.program_code, cur_scope, _program_module.file_name, ns_cache, currentUnitLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
|
StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
|
||||||
|
|
@ -3361,7 +3375,7 @@ namespace CodeCompletion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CompileImportedDependencies(statement_list statementList, string fileName, Hashtable ns_cache, List<string> usedUnitNames, Languages.Facade.ILanguage currentUnitLanguage)
|
private void CompileImportedDependencies(statement_list statementList, SymScope cur_scope, string fileName, Hashtable ns_cache, Languages.Facade.ILanguage currentUnitLanguage)
|
||||||
{
|
{
|
||||||
var importStatements = statementList.list.Where(st => st is import_statement || st is from_import_statement);
|
var importStatements = statementList.list.Where(st => st is import_statement || st is from_import_statement);
|
||||||
|
|
||||||
|
|
@ -3374,17 +3388,20 @@ namespace CodeCompletion
|
||||||
CompileImportedUnit(unitNode.name, import, import.modules_names,
|
CompileImportedUnit(unitNode.name, import, import.modules_names,
|
||||||
Path.GetDirectoryName(fileName),
|
Path.GetDirectoryName(fileName),
|
||||||
cur_scope, unl, currentUnitLanguage);
|
cur_scope, unl, currentUnitLanguage);
|
||||||
|
|
||||||
usedUnitNames.Add(unitNode.name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (importStatement is from_import_statement fromImport)
|
else if (importStatement is from_import_statement fromImport)
|
||||||
|
{
|
||||||
|
var comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
|
||||||
|
|
||||||
|
// Стандартные модули подсоединятся автоматически (import в другой ветке в любом случае нужен)
|
||||||
|
if (currentUnitLanguage.SystemUnitNames.Contains(cur_scope.Name, comparer)
|
||||||
|
|| !currentUnitLanguage.SystemUnitNames.Contains(fromImport.module_name.name, comparer))
|
||||||
{
|
{
|
||||||
CompileImportedUnit(fromImport.module_name.name, fromImport, fromImport.imported_names,
|
CompileImportedUnit(fromImport.module_name.name, fromImport, fromImport.imported_names,
|
||||||
Path.GetDirectoryName(fileName),
|
Path.GetDirectoryName(fileName),
|
||||||
cur_scope, unl, currentUnitLanguage);
|
cur_scope, unl, currentUnitLanguage);
|
||||||
|
}
|
||||||
usedUnitNames.Add(fromImport.module_name.name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -775,10 +775,10 @@ namespace CodeCompletion
|
||||||
if (members == null) return null;
|
if (members == null) return null;
|
||||||
//if (loc != null && loc.begin_line_num <= line && loc.end_line_num >= line && loc.begin_column_num <= column && loc.end_column_num >= column)
|
//if (loc != null && loc.begin_line_num <= line && loc.end_line_num >= line && loc.begin_column_num <= column && loc.end_column_num >= column)
|
||||||
if (IsInScope(loc, line, column))
|
if (IsInScope(loc, line, column))
|
||||||
res = this;
|
minScope = res = this;
|
||||||
TypeScope ts = this as TypeScope;
|
TypeScope ts = this as TypeScope;
|
||||||
if (res == null && ts != null && ts.predef_loc != null && IsInScope(ts.predef_loc, line, column))
|
if (res == null && ts != null && ts.predef_loc != null && IsInScope(ts.predef_loc, line, column))
|
||||||
res = this;
|
minScope = res = this;
|
||||||
foreach (SymScope ss in members)
|
foreach (SymScope ss in members)
|
||||||
if (this != ss && this.topScope != ss && ss.loc != null && (loc == null || loc != null && loc.file_name != null && ss.loc.file_name == loc.file_name))
|
if (this != ss && this.topScope != ss && ss.loc != null && (loc == null || loc != null && loc.file_name != null && ss.loc.file_name == loc.file_name))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ namespace Languages.Facade
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Названия системных модулей (стандартной библиотеки и др.)
|
/// Названия системных модулей (стандартной библиотеки и др.)
|
||||||
|
/// Компилируются в порядке добавления в список
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string[] SystemUnitNames { get; }
|
string[] SystemUnitNames { get; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@ namespace PascalABCCompiler
|
||||||
public static readonly string uint_type_name = "longword";//cardinal
|
public static readonly string uint_type_name = "longword";//cardinal
|
||||||
public static readonly string long_type_name = "int64";//int64
|
public static readonly string long_type_name = "int64";//int64
|
||||||
public static readonly string ulong_type_name = "uint64";
|
public static readonly string ulong_type_name = "uint64";
|
||||||
|
public static readonly string biginteger_type_name = "BigInteger";
|
||||||
//public static readonly string decimal_type_name = "decimal";
|
//public static readonly string decimal_type_name = "decimal";
|
||||||
public static readonly string real_type_name = "real";
|
public static readonly string real_type_name = "real";
|
||||||
public static readonly string float_type_name = "single";
|
public static readonly string float_type_name = "single";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from PABCSystem import Object as obj, Write as pas_print
|
from PABCSystem import Object as obj, Write as pas_print
|
||||||
from SPythonSystem import range, len
|
from SPythonSystem import range, len, tuple
|
||||||
|
from SPythonHidden import *
|
||||||
|
|
||||||
def print(*args: obj, **kwargs: str):
|
def print(*args: obj, **kwargs: str):
|
||||||
sep: str = ' '
|
sep: str = ' '
|
||||||
|
|
@ -17,5 +18,11 @@ def print(*args: obj, **kwargs: str):
|
||||||
pas_print(args[len(args) - 1])
|
pas_print(args[len(args) - 1])
|
||||||
pas_print(end)
|
pas_print(end)
|
||||||
|
|
||||||
#def divmod(a: int, b: int) -> (int,int)
|
def divmod(a: int, b: int) -> tuple[int, int]:
|
||||||
# := (a // b, a % b);
|
return (a // b, a % b)
|
||||||
|
|
||||||
|
def divmod(a: float, b: float) -> tuple[float, float]:
|
||||||
|
return (a // b, a % b)
|
||||||
|
|
||||||
|
def divmod(a: bigint, b: bigint) -> tuple[bigint, bigint]:
|
||||||
|
return (a // b, a % b)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Использование кортежей
|
||||||
|
|
||||||
|
a,b = divmod(-7, 3)
|
||||||
|
temp = divmod(-7, 3)
|
||||||
|
t: tuple[int, int] = divmod(-7, 3)
|
||||||
|
t1: tuple[int] = tuple.Create(0) # из одного эл-та пока так
|
||||||
|
|
||||||
|
print(a == t.Item1)
|
||||||
|
print(b == t.Item2)
|
||||||
|
|
@ -7,9 +7,17 @@ uses SPythonSystem;
|
||||||
|
|
||||||
function !Floor(x : real) : integer;
|
function !Floor(x : real) : integer;
|
||||||
|
|
||||||
function !FloorDiv(x: real; y: real): integer;
|
function !Div(x: integer; y: integer): integer;
|
||||||
|
|
||||||
function !FloorMod(x: real; y: real): real;
|
function !Div(x: BigInteger; y: BigInteger): BigInteger;
|
||||||
|
|
||||||
|
function !Div(x: real; y: real): real;
|
||||||
|
|
||||||
|
function !Mod(x: integer; y: integer): integer;
|
||||||
|
|
||||||
|
function !Mod(x: BigInteger; y: BigInteger): BigInteger;
|
||||||
|
|
||||||
|
function !Mod(x: real; y: real): real;
|
||||||
|
|
||||||
type !UnknownType = class
|
type !UnknownType = class
|
||||||
end;
|
end;
|
||||||
|
|
@ -46,8 +54,26 @@ function dict<TKey, TVal>(seqOfPairs: sequence of (TKey, TVal)): dict<TKey, TVal
|
||||||
|
|
||||||
function !Floor(x : real) : integer := PABCSystem.Floor(x);
|
function !Floor(x : real) : integer := PABCSystem.Floor(x);
|
||||||
|
|
||||||
function !FloorDiv(x: real; y: real): integer := PABCSystem.Floor(x / y);
|
function !Div(x: integer; y: integer): integer;
|
||||||
|
begin
|
||||||
|
Result := x div y;
|
||||||
|
if ((x < 0) xor (y < 0)) and (x mod y <> 0) then
|
||||||
|
Result -= 1;
|
||||||
|
end;
|
||||||
|
|
||||||
function !FloorMod(x: real; y: real): real := x - PABCSystem.Floor(x / y) * y;
|
function !Div(x: BigInteger; y: BigInteger): BigInteger;
|
||||||
|
begin
|
||||||
|
Result := x div y;
|
||||||
|
if ((x < 0) xor (y < 0)) and (x mod y <> 0) then
|
||||||
|
Result -= 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function !Div(x: real; y: real): real := System.Math.Floor(x / y);
|
||||||
|
|
||||||
|
function !Mod(x: integer; y: integer): integer := x - !Div(x, y) * y;
|
||||||
|
|
||||||
|
function !Mod(x: BigInteger; y: BigInteger): BigInteger := x - !Div(x, y) * y;
|
||||||
|
|
||||||
|
function !Mod(x: real; y: real): real := x - PABCSystem.Floor(x / y) * y;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
@ -99,9 +99,6 @@ function abs(x: integer): integer;
|
||||||
/// Возвращает абсолютное значение числа
|
/// Возвращает абсолютное значение числа
|
||||||
function abs(x: real): real;
|
function abs(x: real): real;
|
||||||
|
|
||||||
/// Возвращает результат и остаток от целочисленного деления
|
|
||||||
function divmod(a,b: integer): (integer,integer);
|
|
||||||
|
|
||||||
/// Возвращает x в степени y
|
/// Возвращает x в степени y
|
||||||
function pow(x,y: real): real;
|
function pow(x,y: real): real;
|
||||||
/// Возвращает x в целой степени n
|
/// Возвращает x в целой степени n
|
||||||
|
|
@ -522,27 +519,30 @@ function !pow_recursion(x, n: integer): integer;
|
||||||
function !pow_recursion(x, n: biginteger): biginteger;
|
function !pow_recursion(x, n: biginteger): biginteger;
|
||||||
|
|
||||||
// TUPLES BEGIN
|
// TUPLES BEGIN
|
||||||
function CreateTuple<T1, T2>(
|
|
||||||
|
function !CreateTuple<T>(v: T): System.Tuple<T>;
|
||||||
|
|
||||||
|
function !CreateTuple<T1, T2>(
|
||||||
v1: T1; v2: T2
|
v1: T1; v2: T2
|
||||||
): System.Tuple<T1, T2>;
|
): System.Tuple<T1, T2>;
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3>(
|
function !CreateTuple<T1, T2, T3>(
|
||||||
v1: T1; v2: T2; v3: T3
|
v1: T1; v2: T2; v3: T3
|
||||||
): System.Tuple<T1, T2, T3>;
|
): System.Tuple<T1, T2, T3>;
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4>(
|
function !CreateTuple<T1, T2, T3, T4>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4
|
v1: T1; v2: T2; v3: T3; v4: T4
|
||||||
): System.Tuple<T1, T2, T3, T4>;
|
): System.Tuple<T1, T2, T3, T4>;
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4, T5>(
|
function !CreateTuple<T1, T2, T3, T4, T5>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5
|
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5
|
||||||
): System.Tuple<T1, T2, T3, T4, T5>;
|
): System.Tuple<T1, T2, T3, T4, T5>;
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4, T5, T6>(
|
function !CreateTuple<T1, T2, T3, T4, T5, T6>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6
|
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6
|
||||||
): System.Tuple<T1, T2, T3, T4, T5, T6>;
|
): System.Tuple<T1, T2, T3, T4, T5, T6>;
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
|
function !CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7
|
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7
|
||||||
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
|
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
|
||||||
|
|
||||||
|
|
@ -550,12 +550,14 @@ function CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
|
||||||
|
|
||||||
type
|
type
|
||||||
biginteger = PABCSystem.BigInteger;
|
biginteger = PABCSystem.BigInteger;
|
||||||
tuple2<T1, T2> = System.Tuple<T1, T2>;
|
tuple = System.Tuple;
|
||||||
tuple3<T1, T2, T3> = System.Tuple<T1, T2, T3>;
|
!tuple1<T> = System.Tuple<T>;
|
||||||
tuple4<T1, T2, T3, T4> = System.Tuple<T1, T2, T3, T4>;
|
!tuple2<T1, T2> = System.Tuple<T1, T2>;
|
||||||
tuple5<T1, T2, T3, T4, T5> = System.Tuple<T1, T2, T3, T4, T5>;
|
!tuple3<T1, T2, T3> = System.Tuple<T1, T2, T3>;
|
||||||
tuple6<T1, T2, T3, T4, T5, T6> = System.Tuple<T1, T2, T3, T4, T5, T6>;
|
!tuple4<T1, T2, T3, T4> = System.Tuple<T1, T2, T3, T4>;
|
||||||
tuple7<T1, T2, T3, T4, T5, T6, T7> = System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
|
!tuple5<T1, T2, T3, T4, T5> = System.Tuple<T1, T2, T3, T4, T5>;
|
||||||
|
!tuple6<T1, T2, T3, T4, T5, T6> = System.Tuple<T1, T2, T3, T4, T5, T6>;
|
||||||
|
!tuple7<T1, T2, T3, T4, T5, T6, T7> = System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
|
||||||
|
|
||||||
empty_list = class
|
empty_list = class
|
||||||
class function operator implicit<T>(x: empty_list): list<T>;
|
class function operator implicit<T>(x: empty_list): list<T>;
|
||||||
|
|
@ -668,10 +670,6 @@ end;
|
||||||
function abs(x: integer): integer := if x >= 0 then x else -x;
|
function abs(x: integer): integer := if x >= 0 then x else -x;
|
||||||
function abs(x: real): real := PABCSystem.Abs(x);
|
function abs(x: real): real := PABCSystem.Abs(x);
|
||||||
|
|
||||||
function divmod(a,b: integer): (integer,integer)
|
|
||||||
:= (a div b, a mod b);
|
|
||||||
// divmod вещественный аналог надо реализовать на питоне бы
|
|
||||||
|
|
||||||
function pow(x,y: real): real := PABCSystem.Power(x,y);
|
function pow(x,y: real): real := PABCSystem.Power(x,y);
|
||||||
|
|
||||||
function pow(x: real; n: integer): real := PABCSystem.Power(x,n);
|
function pow(x: real; n: integer): real := PABCSystem.Power(x,n);
|
||||||
|
|
@ -777,32 +775,35 @@ function get_keys<K, V>(dct: Dictionary<K, V>):= dct.keys;
|
||||||
function get_values<K, V>(dct: Dictionary<K, V>):= dct.values;
|
function get_values<K, V>(dct: Dictionary<K, V>):= dct.values;
|
||||||
|
|
||||||
// TUPLES BEGIN
|
// TUPLES BEGIN
|
||||||
function CreateTuple<T1, T2>(
|
|
||||||
|
function !CreateTuple<T>(v: T): System.Tuple<T> := Tuple.Create(v);
|
||||||
|
|
||||||
|
function !CreateTuple<T1, T2>(
|
||||||
v1: T1; v2: T2
|
v1: T1; v2: T2
|
||||||
): System.Tuple<T1, T2>
|
): System.Tuple<T1, T2>
|
||||||
:= (v1, v2);
|
:= (v1, v2);
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3>(
|
function !CreateTuple<T1, T2, T3>(
|
||||||
v1: T1; v2: T2; v3: T3
|
v1: T1; v2: T2; v3: T3
|
||||||
): System.Tuple<T1, T2, T3>
|
): System.Tuple<T1, T2, T3>
|
||||||
:= (v1, v2, v3);
|
:= (v1, v2, v3);
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4>(
|
function !CreateTuple<T1, T2, T3, T4>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4
|
v1: T1; v2: T2; v3: T3; v4: T4
|
||||||
): System.Tuple<T1, T2, T3, T4>
|
): System.Tuple<T1, T2, T3, T4>
|
||||||
:= (v1, v2, v3, v4);
|
:= (v1, v2, v3, v4);
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4, T5>(
|
function !CreateTuple<T1, T2, T3, T4, T5>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5
|
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5
|
||||||
): System.Tuple<T1, T2, T3, T4, T5>
|
): System.Tuple<T1, T2, T3, T4, T5>
|
||||||
:= (v1, v2, v3, v4, v5);
|
:= (v1, v2, v3, v4, v5);
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4, T5, T6>(
|
function !CreateTuple<T1, T2, T3, T4, T5, T6>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6
|
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6
|
||||||
): System.Tuple<T1, T2, T3, T4, T5, T6>
|
): System.Tuple<T1, T2, T3, T4, T5, T6>
|
||||||
:= (v1, v2, v3, v4, v5, v6);
|
:= (v1, v2, v3, v4, v5, v6);
|
||||||
|
|
||||||
function CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
|
function !CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
|
||||||
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7
|
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7
|
||||||
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>
|
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>
|
||||||
:= (v1, v2, v3, v4, v5, v6, v7);
|
:= (v1, v2, v3, v4, v5, v6, v7);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from PABCSystem import Object as obj, Write as pas_print
|
from PABCSystem import Object as obj, Write as pas_print
|
||||||
from SPythonSystem import range, len
|
from SPythonSystem import range, len, tuple
|
||||||
|
from SPythonHidden import *
|
||||||
|
|
||||||
def print(*args: obj, **kwargs: str):
|
def print(*args: obj, **kwargs: str):
|
||||||
sep: str = ' '
|
sep: str = ' '
|
||||||
|
|
@ -17,5 +18,11 @@ def print(*args: obj, **kwargs: str):
|
||||||
pas_print(args[len(args) - 1])
|
pas_print(args[len(args) - 1])
|
||||||
pas_print(end)
|
pas_print(end)
|
||||||
|
|
||||||
#def divmod(a: int, b: int) -> (int,int)
|
def divmod(a: int, b: int) -> tuple[int, int]:
|
||||||
# := (a // b, a % b);
|
return (a // b, a % b)
|
||||||
|
|
||||||
|
def divmod(a: float, b: float) -> tuple[float, float]:
|
||||||
|
return (a // b, a % b)
|
||||||
|
|
||||||
|
def divmod(a: bigint, b: bigint) -> tuple[bigint, bigint]:
|
||||||
|
return (a // b, a % b)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue