Исправление 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 PLUS MINUS
|
||||
%left STAR DIVIDE SLASHSLASH PERCENTAGE
|
||||
%right STARSTAR
|
||||
%right UMINUS UPLUS
|
||||
%left BINNOT
|
||||
%right STARSTAR
|
||||
|
||||
|
||||
%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> 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
|
||||
|
|
@ -145,23 +147,14 @@ extended_expr
|
|||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| extended_new_expr
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
extended_new_expr
|
||||
: new_expr
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
// вызов конструктора без скобочек
|
||||
| NEW type_ref
|
||||
{
|
||||
$$ = new new_expr($2, null, false, null, @$);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
type_decl_identifier
|
||||
: ident
|
||||
{
|
||||
|
|
@ -557,7 +550,11 @@ expr
|
|||
// $$ = new bin_expr($1, $4, Operators.NotIn, @$);
|
||||
$$ = 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, @$);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
cls
|
||||
..\..\..\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
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Errors;
|
||||
using PascalABCCompiler.SemanticTree;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.SystemLibrary;
|
||||
|
|
@ -6,6 +7,8 @@ using PascalABCCompiler.TreeConverter;
|
|||
using PascalABCCompiler.TreeRealization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static PascalABCCompiler.StringConstants;
|
||||
|
||||
namespace SPythonSyntaxTreeVisitor
|
||||
{
|
||||
|
|
@ -241,7 +244,7 @@ namespace SPythonSyntaxTreeVisitor
|
|||
}
|
||||
break;*/
|
||||
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")),
|
||||
new expression_list(new semantic_addr_value(right, right.location)), _bin_expr.source_context);
|
||||
|
|
@ -250,26 +253,37 @@ namespace SPythonSyntaxTreeVisitor
|
|||
}
|
||||
break;
|
||||
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;
|
||||
exprlist.Add(new semantic_addr_value(left, left.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);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
exprlist.Add(new semantic_addr_value(left, left.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);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace Languages.SPython.Frontend.Converters
|
|||
|
||||
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 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 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)
|
||||
{
|
||||
|
|
@ -104,22 +104,31 @@ namespace Languages.SPython.Frontend.Converters
|
|||
}
|
||||
}
|
||||
|
||||
// функция нужна для классов list, dict и set из-за наличия одноименных функций в другом модуле
|
||||
public override void visit(template_type_reference _template_type_reference)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case NameKind.ModuleAlias:
|
||||
_named_type_reference.names[0].name = symbolTable.AliasToRealName(name);
|
||||
break;
|
||||
|
||||
case NameKind.ImportedVariableAlias:
|
||||
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[1].name = symbolTable.AliasToRealName(fullName);
|
||||
_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(name);
|
||||
break;
|
||||
|
||||
case NameKind.Unknown:
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ namespace Languages.SPython.Frontend.Converters
|
|||
|
||||
// проверка корректности имён, разрешение неоднозначности
|
||||
// сохранение множества переменных, использующихся как глобальные в 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))
|
||||
return root;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using PascalABCCompiler.Parsers;
|
|||
using PascalABCCompiler.SyntaxTree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Languages.SPython.Frontend.Converters
|
||||
{
|
||||
|
|
@ -13,8 +14,8 @@ namespace Languages.SPython.Frontend.Converters
|
|||
|
||||
private readonly ILanguageInformation languageInformation = Facade.LanguageProvider.Instance.SelectLanguageByName("SPython").LanguageInformation;
|
||||
|
||||
public SymbolTableFillingVisitor(Dictionary<string, Dictionary<string, bool>> par) {
|
||||
symbolTable = new SymbolTable(par);
|
||||
public SymbolTableFillingVisitor(string unitName, Dictionary<string, Dictionary<string, bool>> par) {
|
||||
symbolTable = new SymbolTable(unitName, par);
|
||||
}
|
||||
|
||||
// нужны методы из BaseChangeVisitor, но порядок обхода из WalkingVisitorNew
|
||||
|
|
@ -176,11 +177,15 @@ namespace Languages.SPython.Frontend.Converters
|
|||
{
|
||||
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}",
|
||||
_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 string[] Keywords = {
|
||||
"int", "float", "str", "bool", "tuple", // standard types
|
||||
"int", "float", "str", "bool", "bigint", // standard types
|
||||
"break", "continue", "exit", "halt", // standard ops
|
||||
"true", "false", // constants
|
||||
};
|
||||
|
|
@ -237,12 +242,14 @@ namespace Languages.SPython.Frontend.Converters
|
|||
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;
|
||||
entryScope = new LocalScope();
|
||||
currentScope = entryScope;
|
||||
FillKeywords();
|
||||
|
||||
if (!StandardLibraries.Contains(unitName))
|
||||
AddAliasesFromStandartLibraries();
|
||||
}
|
||||
|
||||
|
|
@ -347,6 +354,17 @@ namespace Languages.SPython.Frontend.Converters
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Languages.SPython.Frontend.Converters
|
|||
throw new SPythonSyntaxVisitorError("LONG_TUPLE_TYPENAME",
|
||||
ttr.source_context, cnt);
|
||||
}
|
||||
ttr.name.names[index].name += cnt;
|
||||
ttr.name.names[index].name = "!tuple" + cnt;
|
||||
}
|
||||
|
||||
base.visit(ttr);
|
||||
|
|
|
|||
|
|
@ -2692,13 +2692,17 @@ namespace CodeCompletion
|
|||
}
|
||||
}
|
||||
|
||||
// Далее импортирумые пользовательские модули компилируются в обратном порядке, стандартные модули в порядке описания
|
||||
|
||||
List<string> usedUnitsNames = new List<string>();
|
||||
|
||||
interface_node _interface_node = _unit_module.interface_part;
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -2714,7 +2718,7 @@ namespace CodeCompletion
|
|||
// компиляция зависимостей из конструкций import и from import
|
||||
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;
|
||||
|
|
@ -3046,6 +3050,8 @@ namespace CodeCompletion
|
|||
{
|
||||
try
|
||||
{
|
||||
var comparer = currentUnitLanguage.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
|
||||
|
||||
// на случай имен модулей, отличающихся от имен файла EVA
|
||||
string realName = GetRealNameForModule(importedName);
|
||||
|
||||
|
|
@ -3060,7 +3066,7 @@ namespace CodeCompletion
|
|||
if (dc.visitor != null)
|
||||
{
|
||||
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
|
||||
|
|
@ -3072,7 +3078,7 @@ namespace CodeCompletion
|
|||
IntellisensePCUReader pcu_rdr = new IntellisensePCUReader();
|
||||
SymScope ss = pcu_rdr.GetUnit(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;
|
||||
|
||||
if (importStatement is import_statement import)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -3112,6 +3118,10 @@ namespace CodeCompletion
|
|||
}
|
||||
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 (fictiveUnit != null)
|
||||
|
|
@ -3270,11 +3280,15 @@ namespace CodeCompletion
|
|||
}
|
||||
}
|
||||
|
||||
// Далее импортирумые пользовательские модули компилируются в обратном порядке, стандартные модули в порядке описания
|
||||
|
||||
List<string> usedUnitsNames = new List<string>();
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -3290,7 +3304,7 @@ namespace CodeCompletion
|
|||
// компиляция зависимостей из конструкций import и from import
|
||||
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;
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
@ -3374,17 +3388,20 @@ namespace CodeCompletion
|
|||
CompileImportedUnit(unitNode.name, import, import.modules_names,
|
||||
Path.GetDirectoryName(fileName),
|
||||
cur_scope, unl, currentUnitLanguage);
|
||||
|
||||
usedUnitNames.Add(unitNode.name);
|
||||
}
|
||||
}
|
||||
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,
|
||||
Path.GetDirectoryName(fileName),
|
||||
cur_scope, unl, currentUnitLanguage);
|
||||
|
||||
usedUnitNames.Add(fromImport.module_name.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -775,10 +775,10 @@ namespace CodeCompletion
|
|||
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 (IsInScope(loc, line, column))
|
||||
res = this;
|
||||
minScope = res = this;
|
||||
TypeScope ts = this as TypeScope;
|
||||
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)
|
||||
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>
|
||||
string[] SystemUnitNames { get; }
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ namespace PascalABCCompiler
|
|||
public static readonly string uint_type_name = "longword";//cardinal
|
||||
public static readonly string long_type_name = "int64";//int64
|
||||
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 real_type_name = "real";
|
||||
public static readonly string float_type_name = "single";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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):
|
||||
sep: str = ' '
|
||||
|
|
@ -17,5 +18,11 @@ def print(*args: obj, **kwargs: str):
|
|||
pas_print(args[len(args) - 1])
|
||||
pas_print(end)
|
||||
|
||||
#def divmod(a: int, b: int) -> (int,int)
|
||||
# := (a // b, a % b);
|
||||
def divmod(a: int, b: int) -> tuple[int, int]:
|
||||
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 !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
|
||||
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 !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.
|
||||
|
|
@ -99,9 +99,6 @@ function abs(x: integer): integer;
|
|||
/// Возвращает абсолютное значение числа
|
||||
function abs(x: real): real;
|
||||
|
||||
/// Возвращает результат и остаток от целочисленного деления
|
||||
function divmod(a,b: integer): (integer,integer);
|
||||
|
||||
/// Возвращает x в степени y
|
||||
function pow(x,y: real): real;
|
||||
/// Возвращает x в целой степени n
|
||||
|
|
@ -522,27 +519,30 @@ function !pow_recursion(x, n: integer): integer;
|
|||
function !pow_recursion(x, n: biginteger): biginteger;
|
||||
|
||||
// TUPLES BEGIN
|
||||
function CreateTuple<T1, T2>(
|
||||
|
||||
function !CreateTuple<T>(v: T): System.Tuple<T>;
|
||||
|
||||
function !CreateTuple<T1, T2>(
|
||||
v1: T1; v2: T2
|
||||
): System.Tuple<T1, T2>;
|
||||
|
||||
function CreateTuple<T1, T2, T3>(
|
||||
function !CreateTuple<T1, T2, T3>(
|
||||
v1: T1; v2: T2; v3: 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
|
||||
): 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
|
||||
): 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
|
||||
): 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
|
||||
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
|
||||
|
||||
|
|
@ -550,12 +550,14 @@ function CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
|
|||
|
||||
type
|
||||
biginteger = PABCSystem.BigInteger;
|
||||
tuple2<T1, T2> = System.Tuple<T1, T2>;
|
||||
tuple3<T1, T2, T3> = System.Tuple<T1, T2, T3>;
|
||||
tuple4<T1, T2, T3, T4> = System.Tuple<T1, T2, T3, T4>;
|
||||
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>;
|
||||
tuple = System.Tuple;
|
||||
!tuple1<T> = System.Tuple<T>;
|
||||
!tuple2<T1, T2> = System.Tuple<T1, T2>;
|
||||
!tuple3<T1, T2, T3> = System.Tuple<T1, T2, T3>;
|
||||
!tuple4<T1, T2, T3, T4> = System.Tuple<T1, T2, T3, T4>;
|
||||
!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
|
||||
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: 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: 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;
|
||||
|
||||
// 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
|
||||
): System.Tuple<T1, T2>
|
||||
:= (v1, v2);
|
||||
|
||||
function CreateTuple<T1, T2, T3>(
|
||||
function !CreateTuple<T1, T2, T3>(
|
||||
v1: T1; v2: T2; v3: T3
|
||||
): System.Tuple<T1, T2, T3>
|
||||
:= (v1, v2, v3);
|
||||
|
||||
function CreateTuple<T1, T2, T3, T4>(
|
||||
function !CreateTuple<T1, T2, T3, T4>(
|
||||
v1: T1; v2: T2; v3: T3; v4: T4
|
||||
): System.Tuple<T1, T2, T3, T4>
|
||||
:= (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
|
||||
): System.Tuple<T1, T2, T3, T4, T5>
|
||||
:= (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
|
||||
): System.Tuple<T1, T2, T3, T4, T5, T6>
|
||||
:= (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
|
||||
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>
|
||||
:= (v1, v2, v3, v4, v5, v6, v7);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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):
|
||||
sep: str = ' '
|
||||
|
|
@ -17,5 +18,11 @@ def print(*args: obj, **kwargs: str):
|
|||
pas_print(args[len(args) - 1])
|
||||
pas_print(end)
|
||||
|
||||
#def divmod(a: int, b: int) -> (int,int)
|
||||
# := (a // b, a % b);
|
||||
def divmod(a: int, b: int) -> tuple[int, int]:
|
||||
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