diff --git a/Compiler/PCU/PCUReader.cs b/Compiler/PCU/PCUReader.cs index 0160c38dc..40cc64215 100644 --- a/Compiler/PCU/PCUReader.cs +++ b/Compiler/PCU/PCUReader.cs @@ -1704,15 +1704,6 @@ namespace PascalABCCompiler.PCU cmn.newslot_awaited = br.ReadByte() == 1; ReadGenericFunctionInformation(cmn); - //if (CanReadObject()) - //{ - // cmn.generic_params = ReadGenericParams(cun.namespaces[0]); - // foreach (common_type_node par in cmn.generic_params) - // { - // par.generic_function_container = cmn; - // ReadTypeParameterEliminations(par); - // } - //} if (br.ReadByte() == 1) //return_value_type { @@ -1741,12 +1732,7 @@ namespace PascalABCCompiler.PCU cmn.num_of_for_cycles = br.ReadInt32(); br.ReadBoolean(); int num_var = br.ReadInt32(); - for (int i = 0; i < num_var; i++) - { - local_variable lv = GetLocalVariable(cmn); - if (lv != cmn.return_variable) - cmn.var_definition_nodes_list.AddElement(lv); - } + GetVariables(cmn, num_var); int num_consts = br.ReadInt32(); for (int i = 0; i < num_consts; i++) { @@ -1764,6 +1750,24 @@ namespace PascalABCCompiler.PCU return cmn; } + private void GetVariables(common_function_node cfn, int num_var) + { + var local_list = new List>(); + for (int i = 0; i < num_var; i++) + { + var tup = GetLocalVariableLazy(cfn); + local_variable lv = tup.Item1; + if (lv != cfn.return_variable) + cfn.var_definition_nodes_list.AddElement(lv); + if (tup.Item2 != -1) + local_list.Add(tup); + } + foreach (var tup in local_list) + { + tup.Item1.inital_value = CreateExpressionWithOffset(tup.Item2); + } + } + private ref_type_node CreateRefType(int offset) { definition_node dn = null; @@ -2782,12 +2786,7 @@ namespace PascalABCCompiler.PCU cnfn.num_of_for_cycles = br.ReadInt32(); int num_var = br.ReadInt32(); if (cnfn.return_value_type != null) num_var--; - for (int i = 0; i < num_var; i++) - { - local_variable lv = GetLocalVariable(cnfn); - if (lv != cnfn.return_variable) - cnfn.var_definition_nodes_list.AddElement(lv); - } + GetVariables(cnfn, num_var); int num_consts = br.ReadInt32(); for (int i = 0; i < num_consts; i++) { @@ -2888,12 +2887,7 @@ namespace PascalABCCompiler.PCU cnfn.num_of_for_cycles = br.ReadInt32(); int num_var = br.ReadInt32(); if (cnfn.return_value_type != null) num_var--; - for (int i = 0; i < num_var; i++) - { - local_variable lv = GetLocalVariable(cnfn); - if (lv != cnfn.return_variable) - cnfn.var_definition_nodes_list.AddElement(lv); - } + GetVariables(cnfn, num_var); int num_consts = br.ReadInt32(); for (int i = 0; i < num_consts; i++) { @@ -2989,12 +2983,7 @@ namespace PascalABCCompiler.PCU AddMember(cffn, offset); int num_var = br.ReadInt32(); if (cffn.return_value_type != null) num_var--; - for (int i = 0; i < num_var; i++) - { - local_variable lv = GetLocalVariable(cffn); - if (lv != cffn.return_variable) - cffn.var_definition_nodes_list.AddElement(lv); - } + GetVariables(cffn, num_var); int num_consts = br.ReadInt32(); for (int i=0; i < num_consts; i++) { @@ -3011,6 +3000,23 @@ namespace PascalABCCompiler.PCU return cffn; } + private Tuple GetLocalVariableLazy(common_function_node func) + { + int offset = (int)br.BaseStream.Position - start_pos; + //int tmp=br.ReadByte(); + local_variable lv = new local_variable(br.ReadString(), func, null); + lv.type = GetTypeReference(); + if (br.ReadBoolean()) lv.set_used_as_unlocal(); + //members[offset] = lv; + AddMember(lv, offset); + int pos = -1; + if (CanReadObject()) + { + pos = br.ReadInt32(); + } + return new Tuple(lv, pos); + } + private local_variable GetLocalVariable(common_function_node func) { int offset = (int)br.BaseStream.Position-start_pos; @@ -3585,7 +3591,16 @@ namespace PascalABCCompiler.PCU br.BaseStream.Seek(tmp, SeekOrigin.Begin); return en; } - + + private expression_node CreateExpressionWithOffset(int pos) + { + int tmp = (int)br.BaseStream.Position; + br.BaseStream.Seek(start_pos + pos, SeekOrigin.Begin); + expression_node en = CreateExpression(); + br.BaseStream.Seek(tmp, SeekOrigin.Begin); + return en; + } + private expression_node CreateEnumConstNode() { return new enum_const_node(br.ReadInt32(),GetTypeReference(),null); @@ -3750,9 +3765,18 @@ namespace PascalABCCompiler.PCU private expression_node CreateLocalVariableReference() { - local_variable lv = GetLocalVariableByOffset(br.ReadInt32()); - local_variable_reference lvr = new local_variable_reference(lv,0,null); - return lvr; + int off = 0; + try + { + off = br.ReadInt32(); + local_variable lv = GetLocalVariableByOffset(off); + local_variable_reference lvr = new local_variable_reference(lv, 0, null); + return lvr; + } + catch + { + throw; + } } private expression_node CreateLocalBlockVariableReference() diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 9484d7e15..775617af3 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -786,7 +786,6 @@ namespace PascalABCCompiler.NETGenerator cur_type = entry_type; CloseTypes();//закрываем типы - entry_type.CreateType(); switch (comp_opt.target) { diff --git a/Parsers/PascalABCParserNewSaushkin/Parser.cs b/Parsers/PascalABCParserNewSaushkin/Parser.cs index 508129a8f..82a695404 100644 --- a/Parsers/PascalABCParserNewSaushkin/Parser.cs +++ b/Parsers/PascalABCParserNewSaushkin/Parser.cs @@ -243,7 +243,7 @@ namespace PascalABCCompiler.PascalABCNewParser localparserhelper = new GPPGParserHelper(Errors, Warnings, FileName); // localparser.parsertools.LineCorrection = -1; syntax_tree_node root = localparserhelper.Parse(Text); - return root as expression; + return root as statement; } public override syntax_tree_node BuildTreeInSpecialMode(string FileName, string Text) diff --git a/TreeConverter/TreeConversion/compilation_context.cs b/TreeConverter/TreeConversion/compilation_context.cs index db25380cc..4a75f054d 100644 --- a/TreeConverter/TreeConversion/compilation_context.cs +++ b/TreeConverter/TreeConversion/compilation_context.cs @@ -231,7 +231,7 @@ namespace PascalABCCompiler.TreeConverter internal convertion_data_and_alghoritms convertion_data_and_alghoritms; private SemanticTree.field_access_level _fal; - + private bool _has_nested_functions; internal syntax_tree_visitor syntax_tree_visitor; private static compilation_context _instance; @@ -301,7 +301,7 @@ namespace PascalABCCompiler.TreeConverter _last_created_function = null; in_parameters_block = false; is_order_independed_method_description = false; - + _has_nested_functions = false; } public bool inStaticArea() @@ -619,6 +619,18 @@ namespace PascalABCCompiler.TreeConverter //\ssyy } + public bool has_nested_functions + { + get + { + return _has_nested_functions; + } + set + { + _has_nested_functions = value; + } + } + //ssyy public common_function_node_stack converted_func_stack { diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index bcfc7e05a..2d2764a0a 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -883,7 +883,7 @@ namespace PascalABCCompiler.TreeConverter if (syntax_tree_visitor.context.converted_func_stack.size > 0) { common_function_node cfn = syntax_tree_visitor.context.converted_func_stack.first(); - if (cfn.is_generic_function) + if (cfn.is_generic_function || !syntax_tree_visitor.context.has_nested_functions && syntax_tree_visitor.context.converted_func_stack.size == 1) { vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc); } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index cf4ad8c63..c8541fe73 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -2500,9 +2500,21 @@ namespace PascalABCCompiler.TreeConverter } } } - + if (context.converting_block() == block_type.function_block && context.converted_func_stack.size == 1) + { + if (_block.defs != null) + foreach (declaration decl in _block.defs.defs) + { + if (decl is procedure_definition) + { + context.has_nested_functions = true; + break; + } + } + } weak_node_test_and_visit(_block.defs); - + if (context.converting_block() == block_type.function_block && context.converted_func_stack.size == 1) + context.has_nested_functions = false; //ssyy добавил генерацию вызова конструктора предка без параметров if (context.converting_block() == block_type.function_block) { diff --git a/VisualPascalABCNET/IB/Debugger/Debugger.cs b/VisualPascalABCNET/IB/Debugger/Debugger.cs index e3b92f256..9ce13d632 100644 --- a/VisualPascalABCNET/IB/Debugger/Debugger.cs +++ b/VisualPascalABCNET/IB/Debugger/Debugger.cs @@ -14,7 +14,6 @@ using VisualPascalABC.Utils; using Debugger; using ICSharpCode.TextEditor; using ICSharpCode.TextEditor.Document; -using VisualPascalABCPlugins; using System.Runtime.ExceptionServices; namespace VisualPascalABC @@ -23,14 +22,14 @@ namespace VisualPascalABC //Klass predostavljaushij informaciju ob otlazhivaemoj programme public class AssemblyHelper { - private static AppDomain ad; private static System.Reflection.Assembly a; private static List ref_modules = new List(); private static Hashtable ns_ht = new Hashtable(); private static Hashtable stand_types = new Hashtable(StringComparer.OrdinalIgnoreCase); private static List unit_types = new List();//spisok tipov-obertok nad moduljami private static List unit_debug_types;//to zhe samoe, no tipy Debugger.Core - + private static DebugType pabc_system_type = null; + static AssemblyHelper() { stand_types["integer"] = typeof(int); @@ -102,14 +101,8 @@ namespace VisualPascalABC { } -// if (a != null) -// { -// System.Reflection.AssemblyName[] refs = a.GetReferencedAssemblies(); -// for (int i=0; i [HandleProcessCorruptedStateExceptionsAttribute] - public RetValue Evaluate(string expr, bool stmt) + public RetValue Evaluate(string expr, bool for_immediate=false) { //VisualEnvironmentCompilerCompiler.ParsersController.GetExpression declaringType = null; names.Clear(); ret_val = default(RetValue); - for_immediate = stmt; + this.for_immediate = for_immediate; string fileName = "test" + System.IO.Path.GetExtension(this.FileName); List Errors = new List(); + List Warnings = new List(); syntax_tree_node e = null; - if (!stmt) - e = vec.StandartCompiler.ParsersController.GetExpression(fileName, expr, Errors, new List()); + if (for_immediate) + { + e = vec.StandartCompiler.ParsersController.GetExpression(fileName, expr, Errors, Warnings); + if (e == null) + { + Errors.Clear(); + e = vec.StandartCompiler.ParsersController.GetStatement(fileName, expr, Errors, Warnings); + } + } else - e = vec.StandartCompiler.ParsersController.GetStatement(fileName, expr, Errors, new List()); + e = vec.StandartCompiler.ParsersController.GetExpression(fileName, expr, Errors, Warnings); RetValue res = new RetValue(); res.syn_err = false; try { @@ -5059,7 +5067,7 @@ namespace VisualPascalABC //throw new UnknownName(var); } - private MethodInfo[] GetMethod(string name) + private MethodInfo[] GetMethods(string name) { List meths = new List(); IList mis = debuggedProcess.SelectedFunction.DeclaringType.GetMember(name, BindingFlags.All); @@ -5068,7 +5076,17 @@ namespace VisualPascalABC if (mi is MethodInfo) meths.Add(mi as MethodInfo); } - + DebugType pabc_system_type = AssemblyHelper.GetPABCSystemType(); + if (pabc_system_type != null) + { + mis = pabc_system_type.GetMember(name, BindingFlags.All); + foreach (MemberInfo mi in mis) + { + if (mi is MethodInfo) + meths.Add(mi as MethodInfo); + } + } + return meths.ToArray(); } @@ -5079,13 +5097,45 @@ namespace VisualPascalABC if (av is ident) { ident e = av as ident; - meths = GetMethod(e.name); + meths = GetMethods(e.name); obj_val = null; } else if (av is dot_node) { dot_node e = av as dot_node; + string name = build_name(e.left); + ident id = e.right as ident; + if (name != null && id != null) + { + Type t = AssemblyHelper.GetType(name); + if (t != null) + { + //DebugType dt = DebugType.Create(this.debuggedProcess.GetModule(name),(uint)t.MetadataToken); + DebugType dt = DebugUtils.GetDebugType(t); + IList mis = new List(); + DebugType tmp = dt; + while (tmp != null && mis.Count == 0) + { + try + { + mis = tmp.GetMember(id.name, BindingFlags.All); + tmp = tmp.BaseType; + } + catch + { + } + } + List meth_list = new List(); + + foreach (MemberInfo mi in mis) + { + if (mi is MethodInfo) + meth_list.Add(mi as MethodInfo); + } + meths = meth_list.ToArray(); + } + } } return meths; } diff --git a/VisualPascalABCNET/IB/Debugger/Utility.cs b/VisualPascalABCNET/IB/Debugger/Utility.cs index 95ae809d0..60d9566f3 100644 --- a/VisualPascalABCNET/IB/Debugger/Utility.cs +++ b/VisualPascalABCNET/IB/Debugger/Utility.cs @@ -17,6 +17,7 @@ namespace VisualPascalABC public static class DebugUtils { private static Hashtable ht = new Hashtable(); + private static Dictionary type_cache = new Dictionary(); static DebugUtils() { @@ -69,7 +70,8 @@ namespace VisualPascalABC name = "mscorlib.dll"; else name = t.Assembly.ManifestModule.ScopeName; - return DebugType.Create(p.GetModule(name), (uint)t.MetadataToken); + DebugType dt = DebugType.Create(p.GetModule(name), (uint)t.MetadataToken); + return dt; } public static DebugType GetDebugType(Type t, List gen_args)