enum type as array indexer
This commit is contained in:
parent
faad7cdd52
commit
f03cc0a610
|
|
@ -13,6 +13,7 @@ namespace PascalABCCompiler
|
||||||
{
|
{
|
||||||
private List<Errors.CompilerWarning> warns = new List<Errors.CompilerWarning>();
|
private List<Errors.CompilerWarning> warns = new List<Errors.CompilerWarning>();
|
||||||
private OptimizerHelper helper = new OptimizerHelper();
|
private OptimizerHelper helper = new OptimizerHelper();
|
||||||
|
private bool extended_mode = false;
|
||||||
|
|
||||||
public Optimizer()
|
public Optimizer()
|
||||||
{
|
{
|
||||||
|
|
@ -44,6 +45,16 @@ namespace PascalABCCompiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddWarning(string message, location loc)
|
||||||
|
{
|
||||||
|
warns.Add(new GenericWarning(message, loc));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddHint(string message, location loc)
|
||||||
|
{
|
||||||
|
warns.Add(new GenericHint(message, loc));
|
||||||
|
}
|
||||||
|
|
||||||
private void VisitCommonNamespaceHeader(common_namespace_node cnn)
|
private void VisitCommonNamespaceHeader(common_namespace_node cnn)
|
||||||
{
|
{
|
||||||
if (!cnn.from_pcu)
|
if (!cnn.from_pcu)
|
||||||
|
|
@ -108,6 +119,8 @@ namespace PascalABCCompiler
|
||||||
|
|
||||||
private void VisitMethod(common_method_node cmn)
|
private void VisitMethod(common_method_node cmn)
|
||||||
{
|
{
|
||||||
|
if (extended_mode)
|
||||||
|
VisitVariables(cmn.var_definition_nodes_list);
|
||||||
foreach (var_definition_node vdn in cmn.var_definition_nodes_list)
|
foreach (var_definition_node vdn in cmn.var_definition_nodes_list)
|
||||||
helper.AddVariable(vdn);
|
helper.AddVariable(vdn);
|
||||||
foreach (common_parameter prm in cmn.parameters)
|
foreach (common_parameter prm in cmn.parameters)
|
||||||
|
|
@ -171,8 +184,34 @@ namespace PascalABCCompiler
|
||||||
|
|
||||||
private common_function_node cur_func=null;
|
private common_function_node cur_func=null;
|
||||||
|
|
||||||
|
private void CheckType(type_node type, expression_node initial_value, location loc)
|
||||||
|
{
|
||||||
|
if (type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
|
||||||
|
{
|
||||||
|
AddHint("DO_NOT_USE_STATIC_ARRAYS", loc);
|
||||||
|
}
|
||||||
|
else if (type.IsPointer && type.element_type.is_value_type && type.element_type is common_type_node)
|
||||||
|
{
|
||||||
|
AddHint("DO_NOT_USE_POINTERS_TO_RECORDS", loc);
|
||||||
|
}
|
||||||
|
else if (type.type_special_kind == SemanticTree.type_special_kind.short_string)
|
||||||
|
{
|
||||||
|
AddHint("DO_NOT_USE_SHORT_STRINGS", loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VisitVariables(local_variable_list var_list)
|
||||||
|
{
|
||||||
|
foreach (local_variable lv in var_list)
|
||||||
|
{
|
||||||
|
CheckType(lv.type, lv.inital_value, lv.loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void VisitCommonNamespaceFunctionNode(common_namespace_function_node cnfn)
|
private void VisitCommonNamespaceFunctionNode(common_namespace_function_node cnfn)
|
||||||
{
|
{
|
||||||
|
if (extended_mode)
|
||||||
|
VisitVariables(cnfn.var_definition_nodes_list);
|
||||||
foreach (var_definition_node vdn in cnfn.var_definition_nodes_list)
|
foreach (var_definition_node vdn in cnfn.var_definition_nodes_list)
|
||||||
helper.AddVariable(vdn);
|
helper.AddVariable(vdn);
|
||||||
foreach (common_parameter prm in cnfn.parameters)
|
foreach (common_parameter prm in cnfn.parameters)
|
||||||
|
|
@ -220,6 +259,8 @@ namespace PascalABCCompiler
|
||||||
|
|
||||||
private void VisitNestedFunction(common_in_function_function_node cnfn)
|
private void VisitNestedFunction(common_in_function_function_node cnfn)
|
||||||
{
|
{
|
||||||
|
if (extended_mode)
|
||||||
|
VisitVariables(cnfn.var_definition_nodes_list);
|
||||||
foreach (var_definition_node vdn in cnfn.var_definition_nodes_list)
|
foreach (var_definition_node vdn in cnfn.var_definition_nodes_list)
|
||||||
helper.AddVariable(vdn);
|
helper.AddVariable(vdn);
|
||||||
foreach (common_parameter prm in cnfn.parameters)
|
foreach (common_parameter prm in cnfn.parameters)
|
||||||
|
|
@ -364,6 +405,22 @@ namespace PascalABCCompiler
|
||||||
|
|
||||||
private void VisitFor(for_node stmt)
|
private void VisitFor(for_node stmt)
|
||||||
{
|
{
|
||||||
|
if (extended_mode)
|
||||||
|
{
|
||||||
|
if (stmt.init_while_expr is basic_function_call)
|
||||||
|
{
|
||||||
|
basic_function_call bfc = stmt.init_while_expr as basic_function_call;
|
||||||
|
if (!(bfc.real_parameters[0] is local_block_variable_reference))
|
||||||
|
AddHint("USE_LOCAL_BLOCK_VARIABLES_FOR_CYCLE_COUNTER", stmt.location);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local_block_variable lbv = (bfc.real_parameters[0] as local_block_variable_reference).var;
|
||||||
|
if (lbv.loc.begin_line_num < stmt.location.begin_line_num || lbv.loc.begin_column_num < stmt.location.end_column_num)
|
||||||
|
AddHint("USE_LOCAL_BLOCK_VARIABLES_CYCLE_COUNTER", stmt.location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VisitStatement(stmt.init_while_expr);
|
||||||
VisitStatement(stmt.initialization_statement);
|
VisitStatement(stmt.initialization_statement);
|
||||||
VisitStatement(stmt.increment_statement);
|
VisitStatement(stmt.increment_statement);
|
||||||
VisitExpression(stmt.while_expr);
|
VisitExpression(stmt.while_expr);
|
||||||
|
|
@ -462,7 +519,8 @@ namespace PascalABCCompiler
|
||||||
|
|
||||||
private void VisitGoto(goto_statement stmt)
|
private void VisitGoto(goto_statement stmt)
|
||||||
{
|
{
|
||||||
|
if (extended_mode)
|
||||||
|
AddHint("DO_NOT_USE_GOTO", stmt.location);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IncreaseNumUseVar(var_definition_node lvr)
|
private void IncreaseNumUseVar(var_definition_node lvr)
|
||||||
|
|
@ -840,6 +898,58 @@ namespace PascalABCCompiler
|
||||||
|
|
||||||
private void VisitCommonNamespaceFunctionCall(common_namespace_function_call en)
|
private void VisitCommonNamespaceFunctionCall(common_namespace_function_call en)
|
||||||
{
|
{
|
||||||
|
if (extended_mode)
|
||||||
|
{
|
||||||
|
string func_name = en.function_node.name.ToLower();
|
||||||
|
if ((func_name == "readln" || func_name == "read") && en.function_node.namespace_node.namespace_name == "PABCSystem")
|
||||||
|
{
|
||||||
|
if (en.parameters.Count == 1)
|
||||||
|
{
|
||||||
|
if (func_name == "readln")
|
||||||
|
func_name = "Readln";
|
||||||
|
else
|
||||||
|
func_name = "Read";
|
||||||
|
compiled_type_node ctn = en.parameters[0].type as compiled_type_node;
|
||||||
|
if (ctn != null)
|
||||||
|
{
|
||||||
|
if (ctn == SystemLibrary.SystemLibrary.integer_type)
|
||||||
|
{
|
||||||
|
AddHint(string.Format("USE_FUNCTION_{0}_INSTEAD", func_name + "Integer"), en.location);
|
||||||
|
}
|
||||||
|
else if (ctn == SystemLibrary.SystemLibrary.double_type)
|
||||||
|
{
|
||||||
|
AddHint(string.Format("USE_FUNCTION_{0}_INSTEAD", func_name + "Real"), en.location);
|
||||||
|
}
|
||||||
|
else if (ctn == SystemLibrary.SystemLibrary.char_type)
|
||||||
|
{
|
||||||
|
AddHint(string.Format("USE_FUNCTION_{0}_INSTEAD", func_name + "Char"), en.location);
|
||||||
|
}
|
||||||
|
else if (ctn == SystemLibrary.SystemLibrary.string_type)
|
||||||
|
{
|
||||||
|
AddHint(string.Format("USE_FUNCTION_{0}_INSTEAD", func_name + "String"), en.location);
|
||||||
|
}
|
||||||
|
else if (ctn == SystemLibrary.SystemLibrary.bool_type)
|
||||||
|
{
|
||||||
|
AddHint(string.Format("USE_FUNCTION_{0}_INSTEAD", func_name + "Boolean"), en.location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (func_name == "writeln")
|
||||||
|
{
|
||||||
|
if (en.parameters.Count >= 3)
|
||||||
|
{
|
||||||
|
foreach (expression_node prm in en.parameters)
|
||||||
|
{
|
||||||
|
if (prm is string_const_node || prm is char_const_node)
|
||||||
|
{
|
||||||
|
AddHint(string.Format("USE_FUNCTION_{0}_INSTEAD", "WritelnFormat"), en.location);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int i = 0; i < en.parameters.Count; i++)
|
for (int i = 0; i < en.parameters.Count; i++)
|
||||||
VisitExpression(en.parameters[i]);
|
VisitExpression(en.parameters[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,19 @@ namespace PascalABCCompiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class HintStringResources
|
||||||
|
{
|
||||||
|
public static string Get(string key)
|
||||||
|
{
|
||||||
|
return PascalABCCompiler.StringResources.Get("HINT_" + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Get(string key, params object[] values)
|
||||||
|
{
|
||||||
|
return (string.Format(Get(key), values));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class CompilerWarningWithLocation : CompilerWarning
|
public class CompilerWarningWithLocation : CompilerWarning
|
||||||
{
|
{
|
||||||
protected location loc;
|
protected location loc;
|
||||||
|
|
@ -43,7 +56,37 @@ namespace PascalABCCompiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GenericWarning : CompilerWarningWithLocation
|
||||||
|
{
|
||||||
|
protected string message;
|
||||||
|
|
||||||
|
public GenericWarning(string message, location loc)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
this.loc = loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
//return ("Possible two type convertions\n"+_en.location.ToString());
|
||||||
|
return WarningStringResources.Get(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GenericHint : GenericWarning
|
||||||
|
{
|
||||||
|
public GenericHint(string message, location loc):base(message, loc)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
//return ("Possible two type convertions\n"+_en.location.ToString());
|
||||||
|
return WarningStringResources.Get(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class UnreachableCodeDetected : CompilerWarningWithLocation
|
public class UnreachableCodeDetected : CompilerWarningWithLocation
|
||||||
{
|
{
|
||||||
public UnreachableCodeDetected(location loc)
|
public UnreachableCodeDetected(location loc)
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,6 @@
|
||||||
type TArr = array[1..3] of integer;
|
type TEnum = (one, two, three);
|
||||||
|
var arr: array[TEnum] of integer;
|
||||||
type TRec = record
|
|
||||||
a : integer;
|
|
||||||
b : real;
|
|
||||||
c : TArr;
|
|
||||||
d : string;
|
|
||||||
e : string[4];
|
|
||||||
f : set of char;
|
|
||||||
|
|
||||||
end;
|
|
||||||
|
|
||||||
var rec1, rec2 : TRec;
|
|
||||||
arr1 : TArr := (1,2,3);
|
|
||||||
arr2 : TArr := (1,2,3);
|
|
||||||
arr3 : TArr := (1,2,4);
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
rec1.a := 2; rec1.b := 2.3; rec1.d := 'abc'; rec1.e := 'abc';
|
arr[three] := 12;
|
||||||
rec1.c := arr1;
|
assert(arr[three] = 12);
|
||||||
rec1.f := ['e','d'];
|
end.
|
||||||
rec2.a := 2; rec2.b := 2.3; rec2.d := 'abc'; rec2.e := 'abc';
|
|
||||||
rec2.c := arr2;
|
|
||||||
rec2.f := ['e','d'];
|
|
||||||
assert(rec1=rec2);
|
|
||||||
rec1.b := 6.3;
|
|
||||||
assert(rec1<>rec2);
|
|
||||||
rec1.c[2] := 8;
|
|
||||||
assert(rec1 <> rec2);
|
|
||||||
assert(arr1=arr2);
|
|
||||||
assert(arr3<>arr1);
|
|
||||||
end.
|
|
||||||
|
|
@ -12131,7 +12131,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
type_node tn = convert_strong(td);
|
type_node tn = convert_strong(td);
|
||||||
internal_interface ii = tn.get_internal_interface(internal_interface_kind.ordinal_interface);
|
internal_interface ii = tn.get_internal_interface(internal_interface_kind.ordinal_interface);
|
||||||
if (ii == null || ((tn is common_type_node) && (tn as common_type_node).IsEnum))
|
if (ii == null /*|| ((tn is common_type_node) && (tn as common_type_node).IsEnum)*/)
|
||||||
{
|
{
|
||||||
AddError(new OrdinalTypeExpected(get_location(td)));
|
AddError(new OrdinalTypeExpected(get_location(td)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ namespace VisualPascalABC
|
||||||
}
|
}
|
||||||
foreach (Breakpoint bp in dbg.Breakpoints)
|
foreach (Breakpoint bp in dbg.Breakpoints)
|
||||||
{
|
{
|
||||||
if (bp.SourcecodeSegment.SourceFilename == fileName && bp.SourcecodeSegment.StartLine == line)
|
if (bp.SourcecodeSegment.SourceFullFilename == fileName && bp.SourcecodeSegment.StartLine == line)
|
||||||
{
|
{
|
||||||
added = true;
|
added = true;
|
||||||
br = bp;
|
br = bp;
|
||||||
|
|
@ -869,8 +869,8 @@ namespace VisualPascalABC
|
||||||
{
|
{
|
||||||
curILOffset = nextStatement.ILOffset;
|
curILOffset = nextStatement.ILOffset;
|
||||||
CurrentLine = nextStatement.StartLine;
|
CurrentLine = nextStatement.StartLine;
|
||||||
//MustDebug = false;
|
MustDebug = false;
|
||||||
MustDebug = ((nextStatement.ILOffset + 1) == nextStatement.ILEnd);
|
//MustDebug = ((nextStatement.ILOffset + 1) == nextStatement.ILEnd);
|
||||||
}
|
}
|
||||||
//MustDebug = false;
|
//MustDebug = false;
|
||||||
//if (remove_breakpoints)
|
//if (remove_breakpoints)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue