foreach по многомерным массивам теперь возвращает правильный тип элемента.
Вернул короткие определения функций - ошибочно запрещал
This commit is contained in:
parent
6c21ef8fdf
commit
b435cbf7fe
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
||||||
public const string Major = "3";
|
public const string Major = "3";
|
||||||
public const string Minor = "0";
|
public const string Minor = "0";
|
||||||
public const string Build = "0";
|
public const string Build = "0";
|
||||||
public const string Revision = "1156";
|
public const string Revision = "1157";
|
||||||
|
|
||||||
public const string MainVersion = Major + "." + Minor;
|
public const string MainVersion = Major + "." + Minor;
|
||||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
%MINOR%=0
|
|
||||||
%REVISION%=1156
|
|
||||||
%COREVERSION%=0
|
%COREVERSION%=0
|
||||||
|
%REVISION%=1157
|
||||||
|
%MINOR%=0
|
||||||
%MAJOR%=3
|
%MAJOR%=3
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -2,7 +2,7 @@
|
||||||
// This CSharp output file generated by Gardens Point LEX
|
// This CSharp output file generated by Gardens Point LEX
|
||||||
// Version: 1.1.3.301
|
// Version: 1.1.3.301
|
||||||
// Machine: SSM
|
// Machine: SSM
|
||||||
// DateTime: 30.01.2016 1:45:16
|
// DateTime: 01.02.2016 20:56:57
|
||||||
// UserName: ?????????
|
// UserName: ?????????
|
||||||
// GPLEX input file <ABCPascal.lex>
|
// GPLEX input file <ABCPascal.lex>
|
||||||
// GPLEX frame file <embedded resource>
|
// GPLEX frame file <embedded resource>
|
||||||
|
|
|
||||||
|
|
@ -3663,10 +3663,6 @@ lambda_procedure_body
|
||||||
{
|
{
|
||||||
$$ = new statement_list($1 as statement, @$);
|
$$ = new statement_list($1 as statement, @$);
|
||||||
}
|
}
|
||||||
/* | tkWhile expr_l1 optional_tk_do while_stmt
|
|
||||||
{
|
|
||||||
$$ = NewWhileStmt($1, $2, $3, $4 as statement, @$);
|
|
||||||
}*/
|
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// GPPG version 1.3.6
|
// GPPG version 1.3.6
|
||||||
// Machine: SSM
|
// Machine: SSM
|
||||||
// DateTime: 30.01.2016 1:45:17
|
// DateTime: 01.02.2016 20:56:57
|
||||||
// UserName: ?????????
|
// UserName: ?????????
|
||||||
// Input file <ABCPascal.y>
|
// Input file <ABCPascal.y>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,5 +116,6 @@ script=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
!define VERSION '3.0.0.1156'
|
!define VERSION '3.0.0.1157'
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<OutputPath>..\bin\</OutputPath>
|
<OutputPath>..\bin\</OutputPath>
|
||||||
|
|
|
||||||
|
|
@ -1554,7 +1554,7 @@ namespace PascalABCCompiler.SyntaxTree
|
||||||
|
|
||||||
public partial class function_lambda_definition
|
public partial class function_lambda_definition
|
||||||
{
|
{
|
||||||
public object RealSemTypeOfResExpr = null; // Result := ex; - семантический тип ex - нужно для лучщего выбора среди перегруженных методов с параметрами-лямбдами
|
public object RealSemTypeOfResExpr = null; // Result := ex; - семантический тип ex - нужно для лучшего выбора среди перегруженных методов с параметрами-лямбдами
|
||||||
public object RealSemTypeOfResult = null;
|
public object RealSemTypeOfResult = null;
|
||||||
|
|
||||||
public function_lambda_definition(string name, formal_parameters formalPars, type_definition returnType, statement_list body, SourceContext sc)
|
public function_lambda_definition(string name, formal_parameters formalPars, type_definition returnType, statement_list body, SourceContext sc)
|
||||||
|
|
|
||||||
14
TestSuite/06_ShortFunc.pas
Normal file
14
TestSuite/06_ShortFunc.pas
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
function Sqr3(x: integer) := x*x*x;
|
||||||
|
|
||||||
|
function CircleLen(r: real): real := 2 * Pi * r;
|
||||||
|
|
||||||
|
function Hypot(a,b: real) := sqrt(a*a + b*b);
|
||||||
|
|
||||||
|
function Len(x1,y1,x2,y2: real) := Hypot(x2-x1,y2-y1);
|
||||||
|
|
||||||
|
function DigitCount(x: integer) := abs(x).ToString.Length;
|
||||||
|
|
||||||
|
begin
|
||||||
|
writeln(Hypot(3,4));
|
||||||
|
writeln(DigitCount(-1234));
|
||||||
|
end.
|
||||||
12
TestSuite/matrforeach.pas
Normal file
12
TestSuite/matrforeach.pas
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
begin
|
||||||
|
var a := new integer[2,3]((1,2,3),(4,5,6));
|
||||||
|
var s := 0;
|
||||||
|
foreach var x in a do
|
||||||
|
s += x;
|
||||||
|
Print(s);
|
||||||
|
|
||||||
|
var s1 := 0.0;
|
||||||
|
var b := Lst(2.5,3.5,4.5);
|
||||||
|
foreach var x in b do
|
||||||
|
s1 += x;
|
||||||
|
end.
|
||||||
|
|
@ -24,10 +24,12 @@ namespace TreeConverter.LambdaExpressions
|
||||||
resultExpressionsTypes = new List<Tuple<type_node, expression, expression_node>>();
|
resultExpressionsTypes = new List<Tuple<type_node, expression, expression_node>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private type_node GetMostCommonType()
|
private type_node GetMostCommonType(int kind = 0)
|
||||||
{
|
{
|
||||||
if (resultExpressionsTypes.Count == 0)
|
if (resultExpressionsTypes.Count == 0)
|
||||||
|
if (kind==0)
|
||||||
syntaxTreeVisitor.AddError(syntaxTreeVisitor.get_location(lambdaHeader), "IMPOSSIBLE_TO_INFER_RESULT_TYPE_IN_LAMBDA");
|
syntaxTreeVisitor.AddError(syntaxTreeVisitor.get_location(lambdaHeader), "IMPOSSIBLE_TO_INFER_RESULT_TYPE_IN_LAMBDA");
|
||||||
|
else syntaxTreeVisitor.AddError(syntaxTreeVisitor.get_location(lambdaHeader), "IMPOSSIBLE_TO_INFER_RESULT_TYPE");
|
||||||
|
|
||||||
var mostCommonType = resultExpressionsTypes[0].Item1;
|
var mostCommonType = resultExpressionsTypes[0].Item1;
|
||||||
for (var i = 1; i < resultExpressionsTypes.Count; i++)
|
for (var i = 1; i < resultExpressionsTypes.Count; i++)
|
||||||
|
|
@ -44,10 +46,10 @@ namespace TreeConverter.LambdaExpressions
|
||||||
return mostCommonType;
|
return mostCommonType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public type_node InferResultType()
|
public type_node InferResultType(int kind = 0)
|
||||||
{
|
{
|
||||||
ProcessNode(lambdaBody);
|
ProcessNode(lambdaBody);
|
||||||
return GetMostCommonType();
|
return GetMostCommonType(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void visit(statement_list stmtList)
|
public override void visit(statement_list stmtList)
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Поиск всех result - ов
|
#region Поиск всех result - ов
|
||||||
public class ResultNodesSearcher : SyntaxTree.WalkingVisitorNew
|
public class ResultNodesSearcher : SyntaxTree.WalkingVisitorNew // Нигде в проекте не используется потому что expr могут использовать локальные переменные, тип которых неизвестен до семантического разбора
|
||||||
{
|
{
|
||||||
public List<expression> exprList = new List<expression>();
|
public List<expression> exprList = new List<expression>();
|
||||||
public ResultNodesSearcher(syntax_tree_node root)
|
public ResultNodesSearcher(syntax_tree_node root)
|
||||||
|
|
|
||||||
|
|
@ -10893,13 +10893,12 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
|
|
||||||
public override void visit(SyntaxTree.procedure_definition _procedure_definition)
|
public override void visit(SyntaxTree.procedure_definition _procedure_definition)
|
||||||
{
|
{
|
||||||
var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null
|
// SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип
|
||||||
? _procedure_definition.proc_header.name.meth_name
|
|
||||||
: null;
|
|
||||||
// SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести его
|
|
||||||
var fh = (_procedure_definition.proc_header as SyntaxTree.function_header);
|
var fh = (_procedure_definition.proc_header as SyntaxTree.function_header);
|
||||||
if (fh != null && fh.return_type == null)
|
if (fh != null && fh.return_type == null)
|
||||||
{
|
{
|
||||||
|
// попытаемся поступить как в лямбдах
|
||||||
|
//fh.return_type = new semantic_type_node(new LambdaResultTypeInferrer(fh, _procedure_definition.proc_body, this).InferResultType(1));
|
||||||
var bl = _procedure_definition.proc_body as SyntaxTree.block;
|
var bl = _procedure_definition.proc_body as SyntaxTree.block;
|
||||||
if (bl != null && bl.program_code != null)
|
if (bl != null && bl.program_code != null)
|
||||||
{
|
{
|
||||||
|
|
@ -10912,6 +10911,10 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//\ SSM
|
//\ SSM
|
||||||
|
|
||||||
|
var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null
|
||||||
|
? _procedure_definition.proc_header.name.meth_name
|
||||||
|
: null;
|
||||||
if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1)
|
if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1)
|
||||||
AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED");
|
AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED");
|
||||||
if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name))
|
if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name))
|
||||||
|
|
@ -11006,7 +11009,6 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
}
|
}
|
||||||
//\lroman//
|
//\lroman//
|
||||||
|
|
||||||
|
|
||||||
//ssyy
|
//ssyy
|
||||||
if (context.converted_template_type != null)
|
if (context.converted_template_type != null)
|
||||||
{
|
{
|
||||||
|
|
@ -11315,7 +11317,11 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
AddError(new SimpleSemanticError(cmmn.loc, "OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS"));
|
AddError(new SimpleSemanticError(cmmn.loc, "OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS"));
|
||||||
}
|
}
|
||||||
else if (cmmn.parameters.Count != expected_params)
|
else if (cmmn.parameters.Count != expected_params)
|
||||||
AddError(new SimpleSemanticError(cmmn.loc, "OPERATORS_SHOULD_HAVE_{0}_PARAMETERS",expected_params));
|
{
|
||||||
|
if (expected_params==1)
|
||||||
|
AddError(new SimpleSemanticError(cmmn.loc, "OPERATOR_SHOULD_HAVE_1_PARAMETER"));
|
||||||
|
else AddError(new SimpleSemanticError(cmmn.loc, "OPERATOR_SHOULD_HAVE_2_PARAMETERS"));
|
||||||
|
}
|
||||||
bool has_types = false;
|
bool has_types = false;
|
||||||
foreach (parameter p in cmmn.parameters)
|
foreach (parameter p in cmmn.parameters)
|
||||||
{
|
{
|
||||||
|
|
@ -11357,7 +11363,11 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
AddError(new SimpleSemanticError(cnfn.loc, "OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS"));
|
AddError(new SimpleSemanticError(cnfn.loc, "OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS"));
|
||||||
}
|
}
|
||||||
else if (cnfn.parameters.Count != expected_params)
|
else if (cnfn.parameters.Count != expected_params)
|
||||||
AddError(new SimpleSemanticError(cnfn.loc, "OPERATORS_SHOULD_HAVE_{0}_PARAMETERS", expected_params));
|
{
|
||||||
|
if (expected_params == 1)
|
||||||
|
AddError(new SimpleSemanticError(cnfn.loc, "OPERATOR_SHOULD_HAVE_1_PARAMETER"));
|
||||||
|
else AddError(new SimpleSemanticError(cnfn.loc, "OPERATOR_SHOULD_HAVE_2_PARAMETERS"));
|
||||||
|
}
|
||||||
bool has_types = false;
|
bool has_types = false;
|
||||||
foreach (parameter p in cnfn.parameters)
|
foreach (parameter p in cnfn.parameters)
|
||||||
{
|
{
|
||||||
|
|
@ -15918,6 +15928,12 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (tn.element_type != null) // значит, это массив любой размерности
|
||||||
|
{
|
||||||
|
elem_type = tn.element_type;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var ttt = tn.ImplementingInterfaces;
|
var ttt = tn.ImplementingInterfaces;
|
||||||
foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces)
|
foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using PascalABCCompiler;
|
|
||||||
using PascalABCCompiler.SyntaxTree;
|
|
||||||
|
|
||||||
namespace SyntaxVisitors
|
|
||||||
{
|
|
||||||
public class AllVarsInProcYields : CollectUpperNamespacesVisitor
|
|
||||||
{
|
|
||||||
public FindMainIdentsVisitor mids = new FindMainIdentsVisitor();
|
|
||||||
|
|
||||||
public Dictionary<procedure_definition, ISet<string>> d = new Dictionary<procedure_definition, ISet<string>>();
|
|
||||||
|
|
||||||
public int countNodesVisited;
|
|
||||||
|
|
||||||
public AllVarsInProcYields()
|
|
||||||
{
|
|
||||||
PrintInfo = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Enter(syntax_tree_node st)
|
|
||||||
{
|
|
||||||
base.Enter(st);
|
|
||||||
countNodesVisited++;
|
|
||||||
if (st is procedure_definition)
|
|
||||||
{
|
|
||||||
// пока вложенные процедуры не анализируются, хотя надо
|
|
||||||
mids.vars.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// сокращение обходимых узлов. Как сделать фильтр по тем узлам, которые необходимо обходить? Например, все операторы (без выражений и описаний), все описания (без операторов)
|
|
||||||
if (st is assign || st is var_def_statement || st is procedure_call || st is procedure_header || st is expression)
|
|
||||||
{
|
|
||||||
visitNode = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override void Exit(syntax_tree_node st)
|
|
||||||
{
|
|
||||||
if (st is procedure_definition)
|
|
||||||
{
|
|
||||||
if (mids.vars.Count>0)
|
|
||||||
{
|
|
||||||
d[st as procedure_definition] = new HashSet<string>(mids.vars);
|
|
||||||
}
|
|
||||||
var fld = new FindLocalDefsVisitor();
|
|
||||||
st.visit(fld);
|
|
||||||
fld.Print();
|
|
||||||
var t = fld.ids.Intersect(mids.vars); // идентификаторы, захваченные из локального контекста
|
|
||||||
|
|
||||||
}
|
|
||||||
base.Exit(st);
|
|
||||||
}
|
|
||||||
public override void visit(yield_node yn)
|
|
||||||
{
|
|
||||||
yn.visit(mids);
|
|
||||||
// mids.vars - надо установить, какие из них - локальные, какие - из этого класса, какие - являются параметрами функции, а какие - глобальные (все остальные)
|
|
||||||
// те, которые являются параметрами, надо скопировать в локальные переменные и переименовать использование везде по ходу данной функции
|
|
||||||
// самое сложное - переменные-поля этого класса - они требуют в создаваемом классе, реализующем итератор, хранить Self текущего класса и добавлять это Self везде по ходу алгоритма
|
|
||||||
// вначале будем считать, что переменные-поля этого класса и переменные-параметры не захватываются yield
|
|
||||||
//base.visit(yn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PrintDict()
|
|
||||||
{
|
|
||||||
foreach (var a in d)
|
|
||||||
{
|
|
||||||
Console.Write("{0}: {1} ", a.Key.proc_header.name.meth_name, a.Value.Count);
|
|
||||||
foreach (var v in a.Value)
|
|
||||||
Console.Write("{0}, ", v);
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine();
|
|
||||||
Console.WriteLine("countNodesVisited={0}", countNodesVisited);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
|
||||||
</startup>
|
</startup>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using PascalABCCompiler;
|
|
||||||
using PascalABCCompiler.SyntaxTree;
|
|
||||||
|
|
||||||
namespace SyntaxVisitors
|
|
||||||
{
|
|
||||||
public class FindLocalDefsVisitor : WalkingVisitorNew // Запускать только для подпрограмм
|
|
||||||
{
|
|
||||||
public ISet<string> ids = new HashSet<string>();
|
|
||||||
private bool indef = false;
|
|
||||||
public override void visit(ident id)
|
|
||||||
{
|
|
||||||
if (indef)
|
|
||||||
ids.Add(id.name);
|
|
||||||
}
|
|
||||||
public override void visit(var_def_statement defs)
|
|
||||||
{
|
|
||||||
indef = true;
|
|
||||||
ProcessNode(defs.vars); // исключаем типы - просматриваем только имена переменных
|
|
||||||
indef = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Print()
|
|
||||||
{
|
|
||||||
foreach (var x in ids)
|
|
||||||
Console.Write(x + ", ");
|
|
||||||
Console.WriteLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FindMainIdentsVisitor : WalkingVisitorNew // в выражении yield это надо будет.
|
|
||||||
{
|
|
||||||
public HashSet<string> vars = new HashSet<string>();
|
|
||||||
public override void visit(ident id)
|
|
||||||
{
|
|
||||||
vars.Add(id.name);
|
|
||||||
}
|
|
||||||
public override void visit(dot_node dn)
|
|
||||||
{
|
|
||||||
ProcessNode(dn.left);
|
|
||||||
if (dn.right.GetType() != typeof(ident))
|
|
||||||
ProcessNode(dn.right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using PascalABCCompiler.Errors;
|
|
||||||
using PascalABCCompiler;
|
|
||||||
using PascalABCCompiler.SyntaxTree;
|
|
||||||
|
|
||||||
namespace SyntaxVisitors
|
|
||||||
{
|
|
||||||
public class ChangeWhileVisitor : BaseChangeVisitor
|
|
||||||
{
|
|
||||||
int lbnum = 0;
|
|
||||||
|
|
||||||
public static ChangeWhileVisitor New
|
|
||||||
{
|
|
||||||
get { return new ChangeWhileVisitor(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string newLabelName()
|
|
||||||
{
|
|
||||||
lbnum++;
|
|
||||||
return "lb#" + lbnum.ToString();
|
|
||||||
}
|
|
||||||
public override void visit(while_node wn)
|
|
||||||
{
|
|
||||||
ProcessNode(wn.statements);
|
|
||||||
var gt1 = new goto_statement(newLabelName());
|
|
||||||
var gt2 = new goto_statement(newLabelName());
|
|
||||||
var gt3 = new goto_statement(newLabelName());
|
|
||||||
|
|
||||||
var if0 = new if_node(wn.expr, gt1, null);
|
|
||||||
var lb3 = new labeled_statement(gt3.label, if0);
|
|
||||||
var lb1 = new labeled_statement(gt1.label, wn.statements);
|
|
||||||
var lb2 = new labeled_statement(gt2.label, new empty_statement());
|
|
||||||
|
|
||||||
var stl = new statement_list(lb3, gt2, lb1, gt3, lb2);
|
|
||||||
|
|
||||||
Replace(wn, stl);
|
|
||||||
// в declarations ближайшего блока добавить описание labels
|
|
||||||
block bl = listNodes.FindLast(x => x is block) as block;
|
|
||||||
|
|
||||||
var ld = new label_definitions(gt1.label, gt2.label, gt3.label);
|
|
||||||
bl.defs.Add(ld);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using PascalABCCompiler;
|
|
||||||
using PascalABCCompiler.SyntaxTree;
|
|
||||||
|
|
||||||
namespace SyntaxVisitors
|
|
||||||
{
|
|
||||||
public class CalcConstExprs : BaseChangeVisitor // вычисление целых и вещественных константных выражений на этапе парсинга
|
|
||||||
{
|
|
||||||
public override void Exit(syntax_tree_node st)
|
|
||||||
{
|
|
||||||
bracket_expr bre = st as bracket_expr;
|
|
||||||
if (bre != null)
|
|
||||||
{
|
|
||||||
if (bre.expr is int32_const)
|
|
||||||
Replace(st, bre.expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bin_expr vs = st as bin_expr;
|
|
||||||
if (vs != null)
|
|
||||||
{
|
|
||||||
if (vs.left is int32_const && vs.right is int32_const)
|
|
||||||
{
|
|
||||||
var a = vs.left as int32_const;
|
|
||||||
var b = vs.right as int32_const;
|
|
||||||
var op = vs.operation_type;
|
|
||||||
|
|
||||||
syntax_tree_node res;
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case Operators.Plus:
|
|
||||||
res = new int32_const(a.val + b.val);
|
|
||||||
break;
|
|
||||||
case Operators.Minus:
|
|
||||||
res = new int32_const(a.val - b.val);
|
|
||||||
break;
|
|
||||||
case Operators.Multiplication:
|
|
||||||
res = new int32_const(a.val * b.val);
|
|
||||||
break;
|
|
||||||
case Operators.Division:
|
|
||||||
res = new double_const((double)a.val / b.val);
|
|
||||||
break;
|
|
||||||
case Operators.Greater:
|
|
||||||
res = new bool_const(a.val > b.val);
|
|
||||||
break;
|
|
||||||
case Operators.Less:
|
|
||||||
res = new bool_const(a.val < b.val);
|
|
||||||
break;
|
|
||||||
case Operators.GreaterEqual:
|
|
||||||
res = new bool_const(a.val >= b.val);
|
|
||||||
break;
|
|
||||||
case Operators.LessEqual:
|
|
||||||
res = new bool_const(a.val <= b.val);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = vs;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Replace(vs, res);
|
|
||||||
}
|
|
||||||
if (vs.left is int32_const && vs.right is double_const || vs.right is int32_const && vs.left is double_const || vs.left is double_const && vs.right is double_const)
|
|
||||||
{
|
|
||||||
double x,y;
|
|
||||||
if (vs.left is int32_const)
|
|
||||||
x = (vs.left as int32_const).val;
|
|
||||||
else
|
|
||||||
x = (vs.left as double_const).val;
|
|
||||||
if (vs.right is int32_const)
|
|
||||||
y = (vs.right as int32_const).val;
|
|
||||||
else
|
|
||||||
y = (vs.right as double_const).val;
|
|
||||||
|
|
||||||
var op = vs.operation_type;
|
|
||||||
|
|
||||||
syntax_tree_node res;
|
|
||||||
switch (op)
|
|
||||||
{
|
|
||||||
case Operators.Plus:
|
|
||||||
res = new double_const(x + y);
|
|
||||||
break;
|
|
||||||
case Operators.Minus:
|
|
||||||
res = new double_const(x - y);
|
|
||||||
break;
|
|
||||||
case Operators.Multiplication:
|
|
||||||
res = new double_const(x * y);
|
|
||||||
break;
|
|
||||||
case Operators.Division:
|
|
||||||
res = new double_const(x / y);
|
|
||||||
break;
|
|
||||||
case Operators.Greater:
|
|
||||||
res = new bool_const(x > y);
|
|
||||||
break;
|
|
||||||
case Operators.Less:
|
|
||||||
res = new bool_const(x < y);
|
|
||||||
break;
|
|
||||||
case Operators.GreaterEqual:
|
|
||||||
res = new bool_const(x >= y);
|
|
||||||
break;
|
|
||||||
case Operators.LessEqual:
|
|
||||||
res = new bool_const(x <= y);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = vs;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Replace(vs, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Exit(st); // это обязательно!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
|
@ -92,6 +92,8 @@ EVENT_MUST_BE_IN_CLASS_OR_NAMESPACE=Events must be declared in class or unit onl
|
||||||
RECORD_CONST_NOT_ALLOWED_{0}=Incompatible types '{0}' and record
|
RECORD_CONST_NOT_ALLOWED_{0}=Incompatible types '{0}' and record
|
||||||
ONLY_CLASS_CAN_BE_PARTIAL=partial is applicable to classes only
|
ONLY_CLASS_CAN_BE_PARTIAL=partial is applicable to classes only
|
||||||
OPERATORS_SHOULD_HAVE_{0}_PARAMETERS={0} parameter(s) expected
|
OPERATORS_SHOULD_HAVE_{0}_PARAMETERS={0} parameter(s) expected
|
||||||
|
OPERATOR_SHOULD_HAVE_1_PARAMETER=1 parameter expected
|
||||||
|
OPERATOR_SHOULD_HAVE_2_PARAMETERS=2 parameters expected
|
||||||
OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS=1 or 2 parameters expected
|
OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS=1 or 2 parameters expected
|
||||||
LEAST_ONE_PARAMETER_TYPE_SHOULD_EQ_DECLARING_TYPE_{0}=At least one parameter should have type {0}
|
LEAST_ONE_PARAMETER_TYPE_SHOULD_EQ_DECLARING_TYPE_{0}=At least one parameter should have type {0}
|
||||||
EXTENSION_ATTRIBUTE_ONLY_FOR_NAMESPACE_FUNCTIONS_ALLOWED=extensionmethod attribute can be applied only to global functions
|
EXTENSION_ATTRIBUTE_ONLY_FOR_NAMESPACE_FUNCTIONS_ALLOWED=extensionmethod attribute can be applied only to global functions
|
||||||
|
|
|
||||||
6
bin/Lng/Eng/SemanticErrors_ms.dat
Normal file
6
bin/Lng/Eng/SemanticErrors_ms.dat
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
%PREFIX%=SEMANTICERROR_
|
||||||
|
CAN_NOT_READ=Can not read data of this type
|
||||||
|
TUPLE_EXPECTED=Tuple expected
|
||||||
|
TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT=Too many elements on the left side of tuple assignment
|
||||||
|
ONLY_BASE_ASSIGNMENT_FOR_TUPLE=Tuple allows only base assignment :=
|
||||||
|
TUPLE_TYPE_ERROR=Bad element in Tuple type
|
||||||
21
bin/Lng/Eng/SemanticErrors_rs.dat
Normal file
21
bin/Lng/Eng/SemanticErrors_rs.dat
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
%PREFIX%=SEMANTICERROR_
|
||||||
|
UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE=Unable to convert functional type to procedural type
|
||||||
|
ILLEGAL_PARAMETERS_IN_LAMBDA=Wrong types of parameters in lambda expression
|
||||||
|
ILLEGAL_LAMBDA_VARIABLE_TYPE=Wrong type of variable lambda expression is assigned to
|
||||||
|
ILLEGAL_LAMBDA_PARAMETERS_NUMBER=Wrong number of formal parameters in lambda expression
|
||||||
|
IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA=It is impossible to infer types of parameters in lambda expression. Specify variable type to which you assign a lambda expression
|
||||||
|
IMPOSSIBLE_TO_INFER_RESULT_TYPE_IN_LAMBDA=It is impossible to infer result type of lambda expression
|
||||||
|
IMPOSSIBLE_TO_INFER_RESULT_TYPE=It is impossible to infer result type
|
||||||
|
NESTED_LAMBDAS_ARE_NOT_SUPPORTED_IN_THIS_VERSION_OF_COMPILER=Nested lambda expressions are not supported
|
||||||
|
LAMBDAS_ARE_NOT_ALLOWED_IN_NESTED_SUBPROGRAM=Lambda expressions are not allowed in nested subprograms
|
||||||
|
THIS_TYPE_OF_VARIABLES_CANNOT_BE_CAPTURED=This type of variable can't be captured
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_FOREACH_IN_WHAT_STATEMENT=Lambda expressions are not allowed in foreach cycle header
|
||||||
|
CANNOT_CAPTURE_NON_VALUE_PARAMETERS=Non-value parameters of subprograms can't be captured
|
||||||
|
LAMBDAS_NOT_ALLOWED_WHEN_NESTED_SUBPROGRAMMES_ARE_USED=Lambda expressions are not allowed in subprograms with nested subprograms
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_DECLARATIONS_SECTION=Lambda expressions are not allowed in declaration section
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_FIELDS_INITIALIZATION=Lambda expressions are not allowed in field initialization
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_INITIALIZATION_PART_OF_MODULE=Lambda expressions are not allowed in initialization part of module
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_FINALIZATION_PART_OF_MODULE=Lambda expressions are not allowed in finalization part of module
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_INTERFACE_PART_OF_MODULE_IN_INIT=Lambda expressions as variable initializers are not allowed in interface part of module
|
||||||
|
LAMBDAS_NOT_ALLOWED_IN_IMPLEMENTATION_PART_OF_MODULE_IN_INIT=Lambda expressions as variable initializers are not allowed in implementation part of module
|
||||||
|
USING_CAPTURED_PARAMETERS_IS_NOT_ALLOWED_IN_INITIALIZERS=Capture of parameter in lambda in subprogram definition section is not allowed
|
||||||
|
|
@ -94,6 +94,8 @@ ONLY_CLASS_CAN_BE_PARTIAL=partial применим только к класса
|
||||||
ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED=Использование анонимных делегатов в данном контексте недопустимо. Опишите тип делегата явно
|
ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED=Использование анонимных делегатов в данном контексте недопустимо. Опишите тип делегата явно
|
||||||
PARAMETER_REFERENCE_IN_DEFAULT_PARAMETER_NOT_ALLOWED=Использование параметров подпрограммы в значении параметра по умолчанию недопустимо
|
PARAMETER_REFERENCE_IN_DEFAULT_PARAMETER_NOT_ALLOWED=Использование параметров подпрограммы в значении параметра по умолчанию недопустимо
|
||||||
OPERATORS_SHOULD_HAVE_{0}_PARAMETERS=Ожидался {0} параметр(а)
|
OPERATORS_SHOULD_HAVE_{0}_PARAMETERS=Ожидался {0} параметр(а)
|
||||||
|
OPERATOR_SHOULD_HAVE_1_PARAMETER=Ожидался 1 параметр
|
||||||
|
OPERATOR_SHOULD_HAVE_2_PARAMETERS=Ожидалось 2 параметра
|
||||||
OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS=Ожидались 1 или 2 параметра
|
OPERATORS_SHOULD_HAVE_1_OR_2_PARAMETERS=Ожидались 1 или 2 параметра
|
||||||
LEAST_ONE_PARAMETER_TYPE_SHOULD_EQ_DECLARING_TYPE_{0}=Один из параметров должен иметь тип {0}
|
LEAST_ONE_PARAMETER_TYPE_SHOULD_EQ_DECLARING_TYPE_{0}=Один из параметров должен иметь тип {0}
|
||||||
EXTENSION_ATTRIBUTE_ONLY_FOR_NAMESPACE_FUNCTIONS_ALLOWED=Атрибут extensionmethod допустим только для глобальных подпрограмм
|
EXTENSION_ATTRIBUTE_ONLY_FOR_NAMESPACE_FUNCTIONS_ALLOWED=Атрибут extensionmethod допустим только для глобальных подпрограмм
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ ILLEGAL_LAMBDA_VARIABLE_TYPE=
|
||||||
ILLEGAL_LAMBDA_PARAMETERS_NUMBER=Неверное количество формальных параметров в лямбда-выражении
|
ILLEGAL_LAMBDA_PARAMETERS_NUMBER=Неверное количество формальных параметров в лямбда-выражении
|
||||||
IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA=Невозможно вывести типы параметров лямбда-выражения, так как явно не указан тип переменной, которой присваивается лямбда-выражение
|
IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA=Невозможно вывести типы параметров лямбда-выражения, так как явно не указан тип переменной, которой присваивается лямбда-выражение
|
||||||
IMPOSSIBLE_TO_INFER_RESULT_TYPE_IN_LAMBDA=Невозможно вывести тип возвращаемого значения лямбда-выражения
|
IMPOSSIBLE_TO_INFER_RESULT_TYPE_IN_LAMBDA=Невозможно вывести тип возвращаемого значения лямбда-выражения
|
||||||
|
IMPOSSIBLE_TO_INFER_RESULT_TYPE=Невозможно вывести тип возвращаемого значения
|
||||||
NESTED_LAMBDAS_ARE_NOT_SUPPORTED_IN_THIS_VERSION_OF_COMPILER=Использование лямбда-выражения внутри другого лямбда-выражения не поддерживается в этой версии компилятора
|
NESTED_LAMBDAS_ARE_NOT_SUPPORTED_IN_THIS_VERSION_OF_COMPILER=Использование лямбда-выражения внутри другого лямбда-выражения не поддерживается в этой версии компилятора
|
||||||
LAMBDAS_ARE_NOT_ALLOWED_IN_NESTED_SUBPROGRAM=Использование лямбда-выражений внутри вложенных подпрограмм запрещено
|
LAMBDAS_ARE_NOT_ALLOWED_IN_NESTED_SUBPROGRAM=Использование лямбда-выражений внутри вложенных подпрограмм запрещено
|
||||||
THIS_TYPE_OF_VARIABLES_CANNOT_BE_CAPTURED=В данной версии компилятора не поддерживается замыкание данного типа символов
|
THIS_TYPE_OF_VARIABLES_CANNOT_BE_CAPTURED=В данной версии компилятора не поддерживается замыкание данного типа символов
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue