assign с first_assignment_defines_type и тестовым примером

This commit is contained in:
Mikhalkovich Stanislav 2024-03-29 13:53:46 +03:00
parent 7d61b271c8
commit f2d4637338
9 changed files with 96 additions and 20 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "9";
public const string Build = "0";
public const string Revision = "3446";
public const string Revision = "3450";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=0
%REVISION%=3446
%REVISION%=3450
%MINOR%=9
%MAJOR%=3

View file

@ -1 +1 @@
3.9.0.3446
3.9.0.3450

View file

@ -1 +1 @@
!define VERSION '3.9.0.3446'
!define VERSION '3.9.0.3450'

View file

@ -384,6 +384,7 @@ namespace PascalABCCompiler.SyntaxTree
{
return string.Format("{0} {1} {2}", to, OperatorServices.ToString(operator_type, LanguageId.PascalABCNET), from);
}
public bool first_assignment_defines_type = false;
}
public partial class bin_expr

View file

@ -19,15 +19,18 @@ namespace SyntaxVisitors.SugarVisitors
public override void visit(assign ass)
{
if ((ass.to as ident).name != "a")
if ((ass.to as ident).name == "a") // это для примера - это надо закомментировать
ass.first_assignment_defines_type = true;
if (!ass.first_assignment_defines_type)
return;
syntax_tree_node p = ass;
while (!(p is PascalABCCompiler.SyntaxTree.block) && p != null)
while (!(p is PascalABCCompiler.SyntaxTree.block) && p != null) // ищем вверх ближайший блок
p = p.Parent;
if (p == null)
if (p == null) // если блока нет, то выходим. Не знаю, почему его может не быть
return;
var typ = new same_type_node(ass.from);
var typ = new named_type_reference("string",ass.source_context); // делаем какой-то правильный тип - всё равно при первом присваивании будем его менять
var decls = (p as block).defs;
var vds = new var_def_statement(ass.to as ident, typ, ass.source_context);
decls.Add(vds);

View file

@ -1,4 +1,4 @@
/// Учебный модуль, реализующий базовые алгоритмы информатики (27.02.2024)
/// Учебный модуль, реализующий базовые алгоритмы информатики (24.03.2024)
unit School;
interface
@ -218,14 +218,25 @@ function PrimeDivisorsCount(n: integer): integer;
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняет функция Refold.
/// Обратное действие выполняет функция DigitsToInt64.
function Digits(n: int64; base: integer := 10): List<integer>;
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняют функции DigitsToInt64 и DigitsToBigInteger.
function Digits(n: BigInteger; base: integer := 10): List<integer>;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function DigitsToInt64(ext: List<integer>; base: integer := 10): int64;
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function DigitsToBigInteger(ext: List<integer>; base: integer := 10): BigInteger;
/// Возвращает список делителей натурального числа n
function Divisors(n: integer): List<integer>;
@ -844,11 +855,11 @@ function PrimeDivisorsCount(Self: integer): integer; extensionmethod := PrimeDiv
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняет функция Refold.
/// Обратное действие выполняет функция DigitsToInt64.
function Digits(n: int64; base: integer): List<integer>;
begin
Result := new List<integer>;
if (n < 0) or (base < 2) then exit;
if (n < 0) or (base < 2) or (base > integer.MaxValue) then exit;
if n = 0 then Result := Lst(0)
else
while n > 0 do
@ -866,6 +877,28 @@ function Digits(Self: integer; base: integer := 10): List<integer>;
function Digits(Self: int64; base: integer := 10): List<integer>;
extensionmethod := Digits(Self, base);
/// Возвращает целочисленный список расширенного представления
/// десятичного числа n по основанию base.
/// По умолчанию base=10 и возвращается список десятичных цифр числа n.
/// Обратное действие выполняют функции DigitsToInt64 и DigitsToBigInteger.
function Digits(n: BigInteger; base: integer): List<integer>;
begin
Result := new List<integer>;
if (n < 0) or (base < 2) or (base > integer.MaxValue) then exit;
if n = 0 then Result := Lst(0)
else
while n > 0 do
begin
var rem := integer(n mod base);
Result.Add(rem);
n := n div base
end;
Result.Reverse
end;
function Digits(Self: Biginteger; base: integer := 10): List<integer>;
extensionmethod := Digits(Self, base);
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits
@ -881,7 +914,24 @@ begin
end;
function DigitsToInt64(Self: List<integer>; base: integer := 10): int64;
extensionmethod := DigitsToInt64(Self, base);
extensionmethod := DigitsToInt64(Self, base);
/// Возвращает целое десятичное число на основе его расширенного представления
/// по основанию base (по умолчанию base=10).
/// Функция выполняет действие, обратное функции Digits,
function DigitsToBigInteger(ext: List<integer>; base: integer): BigInteger;
begin
Result := BigInteger.Zero;
var p := BigInteger.One;
for var i := ext.Count -1 downto 0 do
begin
Result += ext[i] * p;
p *= base
end
end;
function DigitsToBigInteger(Self: List<integer>; base: integer := 10): BigInteger;
extensionmethod := DigitsToBigInteger(Self, base);
{$endregion}

View file

@ -308,17 +308,18 @@ begin
Result := Self;
end;
function LoadFromXaml(fname: string): object;
function ParseXaml(s: string): object;
begin
var s := ReadAllText(fname);
var context := new ParserContext();
context.XmlnsDictionary.Add('','http://schemas.microsoft.com/winfx/2006/xaml/presentation');
context.XmlnsDictionary.Add('x', 'http://schemas.microsoft.com/winfx/2006/xaml');
Result := System.Windows.Markup.XamlReader.Parse(ReadAllText(fname),nil);
Result := System.Windows.Markup.XamlReader.Parse(s,context);
end;
//var s := new System.IO.FileStream(fname, System.IO.FileMode.Open);
//Result := System.Windows.Markup.XamlReader.Load(s);
//s.Close();
function LoadFromXaml(fname: string): object;
begin
var s := ReadAllText(fname);
Result := ParseXaml(s);
end;
// Функции создания элементов управления

View file

@ -22,6 +22,12 @@ namespace PascalABCCompiler.TreeConverter
addressed_expression to;
expression_node from;
// SSM - идея для особого присваивания, по которому находится тип в SymTable
/*var sc = context.CurrentScope;
var ttt = sc.Find("a");
(ttt[0].sym_info as namespace_variable).type = convert_strong(_assign.from).type;*/
AssignCheckAndConvert(_assign, out to, out from);
@ -112,6 +118,21 @@ namespace PascalABCCompiler.TreeConverter
/// </summary>
private void AssignCheckAndConvert(assign _assign, out addressed_expression to, out expression_node from)
{
// SSM 29/03/24
var fromAsLambda0 = _assign.from as function_lambda_definition;
expression_node from0 = null;
if (fromAsLambda0 == null)
{
// Перенёс вычисление from в начало - чтобы потом сделать узел, задающий тип при первом присваивании
from0 = convert_strong(_assign.from);
if (_assign.first_assignment_defines_type) // всегда в этом случае должно быть присваивание := а не += и т.д.
{
var sc = context.CurrentScope;
var ttt = sc.Find((_assign.to as ident).name); // всегда в этом случае должно быть простое имя
(ttt[0].sym_info as namespace_variable).type = from0.type;
}
}
internal_is_assign = true;
to = convert_address_strong(_assign.to);
internal_is_assign = false;
@ -146,7 +167,7 @@ namespace PascalABCCompiler.TreeConverter
}
else
{
from = convert_strong(_assign.from);
from = from0;
ProcessAssigntToAutoType(to, ref from);
}
// end