initializePreDefFunc

decompiled_code:
__int64 initializePreDefFunc()
{
__int64 v0; // rax
__int64 v1; // rax
__int64 v2; // rax
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rax
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // rsi
__int64 v12; // rax

v0 = createPreDefFunc("odd");
addToSymbolTable(symbolTable, v0);
v1 = createPreDefFunc("abs");
addToSymbolTable(symbolTable, v1);
v2 = createPreDefFunc("sqr");
addToSymbolTable(symbolTable, v2);
v3 = createPreDefFunc("sqrt");
addToSymbolTable(symbolTable, v3);
v4 = createPreDefFunc("sin");
addToSymbolTable(symbolTable, v4);
v5 = createPreDefFunc("exp");
addToSymbolTable(symbolTable, v5);
v6 = createPreDefFunc("ln");
addToSymbolTable(symbolTable, v6);
v7 = createPreDefFunc("trunc");
addToSymbolTable(symbolTable, v7);
v8 = createPreDefFunc("round");
addToSymbolTable(symbolTable, v8);
v9 = createPreDefFunc("ord");
addToSymbolTable(symbolTable, v9);
v10 = createPreDefFunc("chr");
addToSymbolTable(symbolTable, v10);
v11 = createPreDefFunc("succ");
addToSymbolTable(symbolTable, v11);
v12 = createPreDefFunc("pred");
addToSymbolTable(symbolTable, v12);
return 0LL;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 v0; // rax
__int64 v1; // rax
__int64 v2; // rax
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rax
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // rsi
__int64 v12; // rax

v0 = func6("odd");
addToSymbolTable(symbolTable, v0);
v1 = func6("abs");
addToSymbolTable(symbolTable, v1);
v2 = func6("sqr");
addToSymbolTable(symbolTable, v2);
v3 = func6("sqrt");
addToSymbolTable(symbolTable, v3);
v4 = func6("sin");
addToSymbolTable(symbolTable, v4);
v5 = func6("exp");
addToSymbolTable(symbolTable, v5);
v6 = func6("ln");
addToSymbolTable(symbolTable, v6);
v7 = func6("trunc");
addToSymbolTable(symbolTable, v7);
v8 = func6("round");
addToSymbolTable(symbolTable, v8);
v9 = func6("ord");
addToSymbolTable(symbolTable, v9);
v10 = func6("chr");
addToSymbolTable(symbolTable, v10);
v11 = func6("succ");
addToSymbolTable(symbolTable, v11);
v12 = func6("pred");
addToSymbolTable(symbolTable, v12);
return 0LL;
}

original_code:
int initializePreDefFunc() {
 struct Symbol *symbol;
 symbol = createPreDefFunc("odd");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("abs");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("sqr");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("sqrt");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("sin");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("exp");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("ln");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("trunc");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("round");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("ord");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("chr");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("succ");
 addToSymbolTable(symbolTable, symbol);
 symbol = createPreDefFunc("pred");
 addToSymbolTable(symbolTable, symbol);
 return 0;
}

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


createNewBoolConst

repo: a-krebs/YACC

decompiled_code:
__int64 __fastcall createNewBoolConst(__int64 a1, int a2)
{
__int64 v2; // rbx
__int64 v3; // rax

v2 = createConstSymbol();
v3 = getPreDefBool(preDefTypeSymbols);
setInnerTypeSymbol(v2, v3);
*(_DWORD *)(*(_QWORD *)(v2 + 16) + 16LL) = a2;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, int a2)
{
__int64 v2; // rbx
__int64 v3; // rax

v2 = createConstSymbol();
v3 = func0(preDefTypeSymbols);
setInnerTypeSymbol(v2, v3);
*(_DWORD *)(*(_QWORD *)(v2 + 16) + 16LL) = a2;
return v2;
}

original_code:
Symbol *createNewBoolConst(char *name, int val) {
 Symbol *symbol = ((void *)0);
 symbol = createConstSymbol(name);
 setInnerTypeSymbol(symbol, getPreDefBool(preDefTypeSymbols));
 symbol->kindPtr.ConstKind->value.Boolean.value = val;
 return symbol;
}

canonical_original_code:
struct Symbol *createNewBoolConst(char *name, int val) {
 struct Symbol *symbol = ((void *)0);
 symbol = createConstSymbol(name);
 setInnerTypeSymbol(symbol, getPreDefBool(preDefTypeSymbols));
 symbol->kindPtr.ConstKind->value.Boolean.value = val;
 return symbol;
}

variable_types:
name
char *

variable_types: val int

variable_types: struct Symbol { char *name; enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 } kind; union kind_union { struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value { struct Boolean { int value; } Boolean; struct Char { unsigned char value; } Char; struct Integer { int value; } Integer; struct Real { double value; } Real; struct String { char *str; unsigned int strlen; } String; } value; } *ConstKind; struct FunctionKind { struct Symbol *typeSym; struct ElementArray { void **data; unsigned int len; unsigned int nElements; } *params; char *label; int invocationInstance; } *FuncKind; struct ParamKind { struct Symbol *typeSym; int byRef; } *ParamKind; struct ProcedureKind { struct ElementArray *params; char *label; } *ProcKind; struct TypeKind { union type_union { struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; } *Array; struct Function { struct ParamArray { struct Param { char *name; enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 } type; struct Symbol *typeSym; } **data; unsigned int len; unsigned int nElements; } *params; struct Symbol *returnTypeSym; char *label; } *Function; struct Procedure { struct ParamArray *params; char *label; } *Procedure; struct Record { struct hash { struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; } *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; } *hash; } *Record; struct Scalar { struct ElementArray *consts; } *Scalar; struct StringType { unsigned int strlen; } *String; struct Subrange { int high; int low; struct Symbol *baseTypeSym; } *Subrange; } typePtr; enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 } type; } *TypeKind; struct VariableKind { struct Symbol *typeSym; int byRef; } *VarKind; } kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; } *

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


createNewIntConst

decompiled_code:
__int64 __fastcall createNewIntConst(__int64 a1, int a2)
{
__int64 v2; // rbx
__int64 v3; // rax

v2 = createConstSymbol();
v3 = getPreDefInt(preDefTypeSymbols);
setInnerTypeSymbol(v2, v3);
*(_DWORD *)(*(_QWORD *)(v2 + 16) + 16LL) = a2;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, int a2)
{
__int64 v2; // rbx
__int64 v3; // rax

v2 = createConstSymbol();
v3 = func2(preDefTypeSymbols);
setInnerTypeSymbol(v2, v3);
*(_DWORD *)(*(_QWORD *)(v2 + 16) + 16LL) = a2;
return v2;
}

original_code:
Symbol *createNewIntConst(char *name, int val) {
 Symbol *symbol = ((void *)0);
 symbol = createConstSymbol(name);
 setInnerTypeSymbol(symbol, getPreDefInt(preDefTypeSymbols));
 symbol->kindPtr.ConstKind->value.Integer.value = val;
 return symbol;
}

canonical_original_code:
struct Symbol *createNewIntConst(char *name, int val) {
 struct Symbol *symbol = ((void *)0);
 symbol = createConstSymbol(name);
 setInnerTypeSymbol(symbol, getPreDefInt(preDefTypeSymbols));
 symbol->kindPtr.ConstKind->value.Integer.value = val;
 return symbol;
}

return_type: struct Symbol { char *name; enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 } kind; union kind_union { struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value { struct Boolean { int value; } Boolean; struct Char { unsigned char value; } Char; struct Integer { int value; } Integer; struct Real { double value; } Real; struct String { char *str; unsigned int strlen; } String; } value; } *ConstKind; struct FunctionKind { struct Symbol *typeSym; struct ElementArray { void **data; unsigned int len; unsigned int nElements; } *params; char *label; int invocationInstance; } *FuncKind; struct ParamKind { struct Symbol *typeSym; int byRef; } *ParamKind; struct ProcedureKind { struct ElementArray *params; char *label; } *ProcKind; struct TypeKind { union type_union { struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; } *Array; struct Function { struct ParamArray { struct Param { char *name; enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 } type; struct Symbol *typeSym; } **data; unsigned int len; unsigned int nElements; } *params; struct Symbol *returnTypeSym; char *label; } *Function; struct Procedure { struct ParamArray *params; char *label; } *Procedure; struct Record { struct hash { struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; } *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; } *hash; } *Record; struct Scalar { struct ElementArray *consts; } *Scalar; struct StringType { unsigned int strlen; } *String; struct Subrange { int high; int low; struct Symbol *baseTypeSym; } *Subrange; } typePtr; enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 } type; } *TypeKind; struct VariableKind { struct Symbol *typeSym; int byRef; } *VarKind; } kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; } *


initializePreDefConstants

decompiled_code:
__int64 initializePreDefConstants()
{
__int64 v0; // rbx
__int64 v1; // rbx
__int64 v2; // rbx

emitBlankLine();
emitSepLine();
emitBlankLine();
emitComment("Pre-defined constants to follow");
emitBlankLine();
emitSepLine();
emitBlankLine();
v0 = createNewBoolConst((__int64)"true", 1);
addToSymbolTable(symbolTable, v0);
setSymbolOffset(v0, symbolTable);
emitConstDecl(v0);
v1 = createNewBoolConst((__int64)"false", 0);
addToSymbolTable(symbolTable, v1);
setSymbolOffset(v1, symbolTable);
emitConstDecl(v1);
v2 = createNewIntConst((__int64)"maxint", 0x7FFFFFFF);
addToSymbolTable(symbolTable, v2);
setSymbolOffset(v2, symbolTable);
emitConstDecl(v2);
return 0LL;
}

canonical_decompiled_code:
__int64 func11()
{
__int64 v0; // rbx
__int64 v1; // rbx
__int64 v2; // rbx

emitBlankLine();
emitSepLine();
emitBlankLine();
emitComment("Pre-defined constants to follow");
emitBlankLine();
emitSepLine();
emitBlankLine();
v0 = func9((__int64)"true", 1);
addToSymbolTable(symbolTable, v0);
setSymbolOffset(v0, symbolTable);
emitConstDecl(v0);
v1 = func9((__int64)"false", 0);
addToSymbolTable(symbolTable, v1);
setSymbolOffset(v1, symbolTable);
emitConstDecl(v1);
v2 = func10((__int64)"maxint", 0x7FFFFFFF);
addToSymbolTable(symbolTable, v2);
setSymbolOffset(v2, symbolTable);
emitConstDecl(v2);
return 0LL;
}

original_code:
int initializePreDefConstants() {
 Symbol *symbol = ((void *)0);
 emitBlankLine();
 emitSepLine();
 emitBlankLine();
 emitComment("Pre-defined constants to follow");
 emitBlankLine();
 emitSepLine();
 emitBlankLine();
 symbol = createNewBoolConst("true", 1);
 addToSymbolTable(symbolTable, symbol);
 setSymbolOffset(symbol, symbolTable);
 emitConstDecl(symbol);
 symbol = createNewBoolConst("false", 0);
 addToSymbolTable(symbolTable, symbol);
 setSymbolOffset(symbol, symbolTable);
 emitConstDecl(symbol);
 symbol = createNewIntConst("maxint", 2147483647);
 addToSymbolTable(symbolTable, symbol);
 setSymbolOffset(symbol, symbolTable);
 emitConstDecl(symbol);
 return 0;
}

canonical_original_code:
int initializePreDefConstants() {
 struct Symbol *symbol = ((void *)0);
 emitBlankLine();
 emitSepLine();
 emitBlankLine();
 emitComment("Pre-defined constants to follow");
 emitBlankLine();
 emitSepLine();
 emitBlankLine();
 symbol = createNewBoolConst("true", 1);
 addToSymbolTable(symbolTable, symbol);
 setSymbolOffset(symbol, symbolTable);
 emitConstDecl(symbol);
 symbol = createNewBoolConst("false", 0);
 addToSymbolTable(symbolTable, symbol);
 setSymbolOffset(symbol, symbolTable);
 emitConstDecl(symbol);
 symbol = createNewIntConst("maxint", 2147483647);
 addToSymbolTable(symbolTable, symbol);
 setSymbolOffset(symbol, symbolTable);
 emitConstDecl(symbol);
 return 0;
}

return_type: int

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }


isValidProcInvocation

decompiled_code:
__int64 __fastcall isValidProcInvocation(const char **a1, __int64 a2)
{
__int64 v2; // r14
__int64 v3; // rdx
__int64 v4; // rcx
unsigned int v5; // ebx
unsigned int v6; // ebp
__int64 v7; // r15
__int64 v8; // r12
__int64 v9; // rax
__int64 v11; // rax
unsigned int v12; // eax
const char *v13; // r13
unsigned int v14; // eax
const char *v15; // rax
__int64 v16; // rax

if ( *((_DWORD *)a1 + 2) == 3 )
{
v2 = *(_QWORD *)a1[2];
if ( v2 )
{
v3 = *(unsigned int *)(v2 + 12);
v4 = *(unsigned int *)(a2 + 12);
if ( (_DWORD)v3 == (_DWORD)v4 )
{
v5 = 0;
v6 = 1;
if ( (_DWORD)v3 )
{
while ( *(_DWORD *)(a2 + 12) > v5 )
{
v7 = *(_QWORD *)getElementAt(a2, v5);
v8 = getElementAt(v2, v5);
v6 = isAssignmentCompat(v8, v7);
if ( !v6 )
{
v12 = getType(v7);
v13 = (const char *)typeToString(v12);
v14 = getType(v8);
v15 = (const char *)typeToString(v14);
v16 = customErrorString(
"Procedure %s expects argument of type %s at index %d, but got argument of type %s",
*a1,
v15,
v5,
v13);
e = recordError(v16, yylineno, colno, 2LL);
return v6;
}
if ( *(_DWORD *)(v2 + 12) <= ++v5 )
return 1;
}
v6 = 1;
}
}
else
{
v11 = customErrorString("Procedure %s expects %d parameters, got %d", *a1, v3, v4);
e = recordError(v11, yylineno, colno, 2LL);
v6 = 0;
}
}
else
{
v6 = 1;
}
}
else
{
v9 = customErrorString("Identifier %s cannot be called as a procedure.", *a1);
e = recordError(v9, yylineno, colno, 2LL);
v6 = 0;
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char **a1, __int64 a2)
{
__int64 v2; // r14
__int64 v3; // rdx
__int64 v4; // rcx
unsigned int v5; // ebx
unsigned int v6; // ebp
__int64 v7; // r15
__int64 v8; // r12
__int64 v9; // rax
__int64 v11; // rax
unsigned int v12; // eax
const char *v13; // r13
unsigned int v14; // eax
const char *v15; // rax
__int64 v16; // rax

if ( *((_DWORD *)a1 + 2) == 3 )
{
v2 = *(_QWORD *)a1[2];
if ( v2 )
{
v3 = *(unsigned int *)(v2 + 12);
v4 = *(unsigned int *)(a2 + 12);
if ( (_DWORD)v3 == (_DWORD)v4 )
{
v5 = 0;
v6 = 1;
if ( (_DWORD)v3 )
{
while ( *(_DWORD *)(a2 + 12) > v5 )
{
v7 = *(_QWORD *)getElementAt(a2, v5);
v8 = getElementAt(v2, v5);
v6 = isAssignmentCompat(v8, v7);
if ( !v6 )
{
v12 = getType(v7);
v13 = (const char *)typeToString(v12);
v14 = getType(v8);
v15 = (const char *)typeToString(v14);
v16 = customErrorString(
"Procedure %s expects argument of type %s at index %d, but got argument of type %s",
*a1,
v15,
v5,
v13);
e = recordError(v16, yylineno, colno, 2LL);
return v6;
}
if ( *(_DWORD *)(v2 + 12) <= ++v5 )
return 1;
}
v6 = 1;
}
}
else
{
v11 = customErrorString("Procedure %s expects %d parameters, got %d", *a1, v3, v4);
e = recordError(v11, yylineno, colno, 2LL);
v6 = 0;
}
}
else
{
v6 = 1;
}
}
else
{
v9 = customErrorString("Identifier %s cannot be called as a procedure.", *a1);
e = recordError(v9, yylineno, colno, 2LL);
v6 = 0;
}
return v6;
}

original_code:
int isValidProcInvocation(Symbol *s, struct ElementArray *ea)
{
 struct ElementArray *params = ((void *)0);
 Symbol *passedParam, *expectedParam = ((void *)0);
 int i;
 if (s->kind != PROC_KIND) {
  errMsg = customErrorString("Identifier %s cannot be called "
      "as a procedure.", s->name);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 params = s->kindPtr.ProcKind->params;
 if (!params) {
  return 1;
 } else if (params->nElements != ea->nElements) {
  errMsg = customErrorString("Procedure %s expects %d "
      "parameters, got %d", s->name, params->nElements,
      ea->nElements);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 for (i = 0; (i < params->nElements) && (i < ea->nElements); i++) {
  passedParam = ((struct treeNode *)getElementAt(ea, i))->symbol;
  expectedParam = (Symbol *) getElementAt(params, i);
  if (!isAssignmentCompat(expectedParam, passedParam)) {
   errMsg = customErrorString("Procedure %s expects "
       "argument of type %s at index %d, but got "
       "argument of type %s", s->name,
       typeToString(getType(expectedParam)), i,
       typeToString(getType(passedParam)));
   e = recordError(errMsg, yylineno, colno,
        SEMANTIC);
   return 0;
  }
 }
 return 1;
}

canonical_original_code:
int isValidProcInvocation(struct Symbol *s, struct ElementArray *ea)
{
 struct ElementArray *params = ((void *)0);
 struct Symbol *passedParam; struct Symbol *expectedParam = ((void *)0);
 int i;
 if (s->kind != PROC_KIND) {
  errMsg = customErrorString("Identifier %s cannot be called "
      "as a procedure.", s->name);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 params = s->kindPtr.ProcKind->params;
 if (!params) {
  return 1;
 } else if (params->nElements != ea->nElements) {
  errMsg = customErrorString("Procedure %s expects %d "
      "parameters, got %d", s->name, params->nElements,
      ea->nElements);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 for (i = 0; (i < params->nElements) && (i < ea->nElements); i++) {
  passedParam = ((struct treeNode *)getElementAt(ea, i))->symbol;
  expectedParam = (struct Symbol *) getElementAt(params, i);
  if (!isAssignmentCompat(expectedParam, passedParam)) {
   errMsg = customErrorString("Procedure %s expects "
       "argument of type %s at index %d, but got "
       "argument of type %s", s->name,
       typeToString(getType(expectedParam)), i,
       typeToString(getType(passedParam)));
   e = recordError(errMsg, yylineno, colno,
        SEMANTIC);
   return 0;
  }
 }
 return 1;
}

variable_types:
ea
struct ElementArray *

variable_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; } *

variable_types: i int

user_defined_types: struct treeNode { struct Symbol *symbol; int opToken; struct treeNode *parent; struct treeNode *left; struct treeNode *right; }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


isValidFuncInvocation

decompiled_code:
__int64 __fastcall isValidFuncInvocation(const char **a1, __int64 a2)
{
__int64 v2; // r12
__int64 v3; // rdx
__int64 v4; // rcx
unsigned int v5; // ebx
__int64 v6; // r13
__int64 v7; // rbp
__int64 result; // rax
__int64 v9; // rax
__int64 v10; // rax
unsigned int v11; // eax
const char *v12; // r12
unsigned int v13; // eax
const char *v14; // rax
__int64 v15; // rax

if ( *((_DWORD *)a1 + 2) == 1 )
{
v2 = *((_QWORD *)a1[2] + 1);
if ( v2 )
{
v3 = *(unsigned int *)(v2 + 12);
v4 = *(unsigned int *)(a2 + 12);
if ( (_DWORD)v3 == (_DWORD)v4 )
{
v5 = 0;
if ( (_DWORD)v3 )
{
while ( 1 )
{
v6 = *(_QWORD *)getElementAt(a2, v5);
v7 = getElementAt(v2, v5);
if ( !(unsigned int)isAssignmentCompat(v7, v6) )
break;
if ( *(_DWORD *)(v2 + 12) <= ++v5 )
goto LABEL_7;
}
v11 = getType(v6);
v12 = (const char *)typeToString(v11);
v13 = getType(v7);
v14 = (const char *)typeToString(v13);
v15 = customErrorString(
"Procedure %s expects argument of type %s at index %d, but got argument of type %s",
*a1,
v14,
v5,
v12);
e = recordError(v15, yylineno, colno, 2LL);
result = 0LL;
}
else
{
LABEL_7:
result = getTypeSym(a1);
}
}
else
{
v10 = customErrorString("Procedure %s expects %d parameters, got %d", *a1, v3, v4);
e = recordError(v10, yylineno, colno, 2LL);
result = 0LL;
}
}
else
{
result = ((__int64 (*)(void))getTypeSym)();
}
}
else
{
v9 = customErrorString("Identifier %s cannot be called as a function.", *a1);
e = recordError(v9, yylineno, colno, 2LL);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(const char **a1, __int64 a2)
{
__int64 v2; // r12
__int64 v3; // rdx
__int64 v4; // rcx
unsigned int v5; // ebx
__int64 v6; // r13
__int64 v7; // rbp
__int64 result; // rax
__int64 v9; // rax
__int64 v10; // rax
unsigned int v11; // eax
const char *v12; // r12
unsigned int v13; // eax
const char *v14; // rax
__int64 v15; // rax

if ( *((_DWORD *)a1 + 2) == 1 )
{
v2 = *((_QWORD *)a1[2] + 1);
if ( v2 )
{
v3 = *(unsigned int *)(v2 + 12);
v4 = *(unsigned int *)(a2 + 12);
if ( (_DWORD)v3 == (_DWORD)v4 )
{
v5 = 0;
if ( (_DWORD)v3 )
{
while ( 1 )
{
v6 = *(_QWORD *)getElementAt(a2, v5);
v7 = getElementAt(v2, v5);
if ( !(unsigned int)isAssignmentCompat(v7, v6) )
break;
if ( *(_DWORD *)(v2 + 12) <= ++v5 )
goto LABEL_7;
}
v11 = getType(v6);
v12 = (const char *)typeToString(v11);
v13 = getType(v7);
v14 = (const char *)typeToString(v13);
v15 = customErrorString(
"Procedure %s expects argument of type %s at index %d, but got argument of type %s",
*a1,
v14,
v5,
v12);
e = recordError(v15, yylineno, colno, 2LL);
result = 0LL;
}
else
{
LABEL_7:
result = getTypeSym(a1);
}
}
else
{
v10 = customErrorString("Procedure %s expects %d parameters, got %d", *a1, v3, v4);
e = recordError(v10, yylineno, colno, 2LL);
result = 0LL;
}
}
else
{
result = ((__int64 (*)(void))getTypeSym)();
}
}
else
{
v9 = customErrorString("Identifier %s cannot be called as a function.", *a1);
e = recordError(v9, yylineno, colno, 2LL);
result = 0LL;
}
return result;
}

original_code:
Symbol *
isValidFuncInvocation(Symbol *s, struct ElementArray *ea)
{
 struct ElementArray *params = ((void *)0);
 Symbol *passedParam, *expectedParam = ((void *)0);
 int i;
 if (s->kind != FUNC_KIND) {
  errMsg = customErrorString("Identifier %s cannot be "
    "called as a function.", s->name);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 params = s->kindPtr.FuncKind->params;
 if (!params) {
  return getTypeSym(s);
 } else if (params->nElements != ea->nElements) {
  errMsg = customErrorString("Procedure %s expects %d "
      "parameters, got %d", s->name, params->nElements,
      ea->nElements);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return ((void *)0);
 }
 for (i = 0; i < params->nElements; i++) {
  passedParam = ((struct treeNode *)getElementAt(ea, i))->symbol;
  expectedParam = (Symbol *) getElementAt(params, i);
  if (!isAssignmentCompat(expectedParam,passedParam)) {
   errMsg = customErrorString("Procedure %s expects "
       "argument of type %s at index %d, but got "
       "argument of type %s", s->name,
       typeToString(getType(expectedParam)),i,
       typeToString(getType(passedParam)));
   e = recordError(errMsg, yylineno, colno, SEMANTIC);
   return ((void *)0);
  }
 }
 return getTypeSym(s);
}

canonical_original_code:
struct Symbol *isValidFuncInvocation(struct Symbol *s, struct ElementArray *ea)
{
 struct ElementArray *params = ((void *)0);
 struct Symbol *passedParam; struct Symbol *expectedParam = ((void *)0);
 int i;
 if (s->kind != FUNC_KIND) {
  errMsg = customErrorString("Identifier %s cannot be "
    "called as a function.", s->name);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 params = s->kindPtr.FuncKind->params;
 if (!params) {
  return getTypeSym(s);
 } else if (params->nElements != ea->nElements) {
  errMsg = customErrorString("Procedure %s expects %d "
      "parameters, got %d", s->name, params->nElements,
      ea->nElements);
  e = recordError(errMsg, yylineno, colno, SEMANTIC);
  return ((void *)0);
 }
 for (i = 0; i < params->nElements; i++) {
  passedParam = ((struct treeNode *)getElementAt(ea, i))->symbol;
  expectedParam = (struct Symbol *) getElementAt(params, i);
  if (!isAssignmentCompat(expectedParam,passedParam)) {
   errMsg = customErrorString("Procedure %s expects "
       "argument of type %s at index %d, but got "
       "argument of type %s", s->name,
       typeToString(getType(expectedParam)),i,
       typeToString(getType(passedParam)));
   e = recordError(errMsg, yylineno, colno, SEMANTIC);
   return ((void *)0);
  }
 }
 return getTypeSym(s);
}

variable_types:
s
struct Symbol *

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


isIOProc

decompiled_code:
_BOOL8 __fastcall isIOProc(__int64 a1)
{
_BOOL4 v1; // edx
const char *v2; // r8

if ( !a1 )
return 0;
v1 = 0;
if ( *(_DWORD *)(a1 + 8) == 3 )
{
v2 = *(const char **)a1;
if ( !strcmp(*(const char **)a1, "read")
|| !strcmp(v2, "readln")
|| !strcmp(v2, "write")
|| (v1 = 0, !strcmp(v2, "writeln")) )
{
v1 = *(_DWORD *)(a1 + 24) == 0;
}
}
return v1;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(__int64 a1)
{
_BOOL4 v1; // edx
const char *v2; // r8

if ( !a1 )
return 0;
v1 = 0;
if ( *(_DWORD *)(a1 + 8) == 3 )
{
v2 = *(const char **)a1;
if ( !strcmp(*(const char **)a1, "read")
|| !strcmp(v2, "readln")
|| !strcmp(v2, "write")
|| (v1 = 0, !strcmp(v2, "writeln")) )
{
v1 = *(_DWORD *)(a1 + 24) == 0;
}
}
return v1;
}

original_code:
int
isIOProc(Symbol *s) {
 if (!s) return 0;
 if (s->kind != PROC_KIND) return 0;
 if ( ( (strcmp(s->name, "read") == 0) ||
      (strcmp(s->name, "readln") == 0) ||
      (strcmp(s->name, "write") == 0) ||
      (strcmp(s->name, "writeln") == 0) ) &&
  (s->lvl == 0) ) {
  return 1;
 }
 return 0;
}

canonical_original_code:
int isIOProc(struct Symbol *s) {
 if (!s) return 0;
 if (s->kind != PROC_KIND) return 0;
 if ( ( (strcmp(s->name, "read") == 0) ||
      (strcmp(s->name, "readln") == 0) ||
      (strcmp(s->name, "write") == 0) ||
      (strcmp(s->name, "writeln") == 0) ) &&
  (s->lvl == 0) ) {
  return 1;
 }
 return 0;
}

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }


isPreDefFunc

decompiled_code:
_BOOL8 __fastcall isPreDefFunc(__int64 a1)
{
_BOOL8 result; // rax
const char *v2; // rbp
int v3; // edx

if ( !a1 )
return 0LL;
result = 0LL;
if ( *(_DWORD *)(a1 + 8) == 1 )
{
v2 = *(const char **)a1;
if ( !strcmp(*(const char **)a1, "abs")
|| !strcmp(v2, "sqr")
|| !strcmp(v2, "sin")
|| !strcmp(v2, "exp")
|| !strcmp(v2, "ln")
|| !strcmp(v2, "sqrt")
|| !strcmp(v2, "trunc")
|| !strcmp(v2, "round")
|| !strcmp(v2, "chr")
|| !strcmp(v2, "odd")
|| !strcmp(v2, "ord")
|| !strcmp(v2, "succ")
|| (v3 = strcmp(v2, "pred"), result = 0LL, !v3) )
{
result = *(_DWORD *)(a1 + 24) == 0;
}
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func3(__int64 a1)
{
_BOOL8 result; // rax
const char *v2; // rbp
int v3; // edx

if ( !a1 )
return 0LL;
result = 0LL;
if ( *(_DWORD *)(a1 + 8) == 1 )
{
v2 = *(const char **)a1;
if ( !strcmp(*(const char **)a1, "abs")
|| !strcmp(v2, "sqr")
|| !strcmp(v2, "sin")
|| !strcmp(v2, "exp")
|| !strcmp(v2, "ln")
|| !strcmp(v2, "sqrt")
|| !strcmp(v2, "trunc")
|| !strcmp(v2, "round")
|| !strcmp(v2, "chr")
|| !strcmp(v2, "odd")
|| !strcmp(v2, "ord")
|| !strcmp(v2, "succ")
|| (v3 = strcmp(v2, "pred"), result = 0LL, !v3) )
{
result = *(_DWORD *)(a1 + 24) == 0;
}
}
return result;
}

original_code:
int isPreDefFunc(Symbol *s) {
 char *name = ((void *)0);
 if (!s) return 0;
 if (s->kind != FUNC_KIND) return 0;
 name = s->name;
 if ( ( (strcmp(name, "abs") == 0) ||
  (strcmp(name, "sqr") == 0) ||
  (strcmp(name, "sin") == 0) ||
  (strcmp(name, "exp") == 0) ||
  (strcmp(name, "ln") == 0) ||
  (strcmp(name, "sqrt") == 0) ||
  (strcmp(name, "trunc") == 0) ||
  (strcmp(name, "round") == 0) ||
  (strcmp(name, "chr") == 0) ||
  (strcmp(name, "odd") == 0) ||
  (strcmp(name, "ord") == 0) ||
  (strcmp(name, "succ") == 0) ||
  (strcmp(name, "pred") == 0) ) &&
   s->lvl == 0) {
     return 1;
 }
 return 0;
}

canonical_original_code:
int isPreDefFunc(struct Symbol *s) {
 char *name = ((void *)0);
 if (!s) return 0;
 if (s->kind != FUNC_KIND) return 0;
 name = s->name;
 if ( ( (strcmp(name, "abs") == 0) ||
  (strcmp(name, "sqr") == 0) ||
  (strcmp(name, "sin") == 0) ||
  (strcmp(name, "exp") == 0) ||
  (strcmp(name, "ln") == 0) ||
  (strcmp(name, "sqrt") == 0) ||
  (strcmp(name, "trunc") == 0) ||
  (strcmp(name, "round") == 0) ||
  (strcmp(name, "chr") == 0) ||
  (strcmp(name, "odd") == 0) ||
  (strcmp(name, "ord") == 0) ||
  (strcmp(name, "succ") == 0) ||
  (strcmp(name, "pred") == 0) ) &&
   s->lvl == 0) {
     return 1;
 }
 return 0;
}

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


getPreDefFuncReturnType

decompiled_code:
__int64 __fastcall getPreDefFuncReturnType(const char **a1, __int64 a2)
{
__int64 result; // rax
const char *v3; // rdx
bool v4; // cf
bool v5; // zf
const char *v6; // rdi
__int64 v7; // rcx
const char *v8; // rsi
char v9; // al
bool v10; // cf
bool v11; // zf
const char *v12; // rdi
__int64 v13; // rcx
char v14; // al
bool v15; // cf
bool v16; // zf
const char *v17; // rdi
__int64 v18; // rcx
char v19; // al
bool v20; // cf
bool v21; // zf
const char *v22; // rdi
__int64 v23; // rcx
char v24; // al
bool v25; // cf
bool v26; // zf
const char *v27; // rdi
__int64 v28; // rcx
const char *v29; // rsi
char v30; // al
bool v31; // cf
bool v32; // zf
const char *v33; // rdi
__int64 v34; // rcx
char v35; // al
bool v36; // cf
bool v37; // zf
const char *v38; // rdi
__int64 v39; // rcx
char v40; // al
bool v41; // cf
bool v42; // zf
const char *v43; // rdi
__int64 v44; // rcx
const char *v45; // rsi
char v46; // al
bool v47; // cf
bool v48; // zf
const char *v49; // rdi
__int64 v50; // rcx
const char *v51; // rsi
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

if ( !a1 )
return 0LL;
result = a2;
v3 = *a1;
if ( strcmp(*a1, "abs") && strcmp(v3, "sqr") && strcmp(v3, "succ") && strcmp(v3, "pred") )
{
v4 = (unsigned __int64)&retaddr < 8;
v5 = &retaddr == 0LL;
v6 = "sin";
v7 = 4LL;
v8 = v3;
do
{
if ( !v7 )
break;
v4 = *v8 < (unsigned int)*v6;
v5 = *v8++ == *v6++;
--v7;
}
while ( v5 );
v9 = (!v4 && !v5) - v4;
v10 = 0;
v11 = v9 == 0;
if ( !v9 )
goto LABEL_43;
v12 = "exp";
v13 = 4LL;
v8 = v3;
do
{
if ( !v13 )
break;
v10 = *v8 < (unsigned int)*v12;
v11 = *v8++ == *v12++;
--v13;
}
while ( v11 );
v14 = (!v10 && !v11) - v10;
v15 = 0;
v16 = v14 == 0;
if ( !v14 )
goto LABEL_43;
v17 = "ln";
v18 = 3LL;
v8 = v3;
do
{
if ( !v18 )
break;
v15 = *v8 < (unsigned int)*v17;
v16 = *v8++ == *v17++;
--v18;
}
while ( v16 );
v19 = (!v15 && !v16) - v15;
v20 = 0;
v21 = v19 == 0;
if ( !v19 )
goto LABEL_43;
v22 = "sqrt";
v23 = 5LL;
v8 = v3;
do
{
if ( !v23 )
break;
v20 = *v8 < (unsigned int)*v22;
v21 = *v8++ == *v22++;
--v23;
}
while ( v21 );
v24 = (!v20 && !v21) - v20;
v25 = 0;
v26 = v24 == 0;
if ( v24 )
{
v27 = "trunc";
v28 = 6LL;
v29 = v3;
do
{
if ( !v28 )
break;
v25 = *v29 < (unsigned int)*v27;
v26 = *v29++ == *v27++;
--v28;
}
while ( v26 );
v30 = (!v25 && !v26) - v25;
v31 = 0;
v32 = v30 == 0;
if ( !v30 )
goto LABEL_45;
v33 = "round";
v34 = 6LL;
v29 = v3;
do
{
if ( !v34 )
break;
v31 = *v29 < (unsigned int)*v33;
v32 = *v29++ == *v33++;
--v34;
}
while ( v32 );
v35 = (!v31 && !v32) - v31;
v36 = 0;
v37 = v35 == 0;
if ( !v35 )
goto LABEL_45;
v38 = "ord";
v39 = 4LL;
v29 = v3;
do
{
if ( !v39 )
break;
v36 = *v29 < (unsigned int)*v38;
v37 = *v29++ == *v38++;
--v39;
}
while ( v37 );
v40 = (!v36 && !v37) - v36;
v41 = 0;
v42 = v40 == 0;
if ( v40 )
{
v43 = "chr";
v44 = 4LL;
v45 = v3;
do
{
if ( !v44 )
break;
v41 = *v45 < (unsigned int)*v43;
v42 = *v45++ == *v43++;
--v44;
}
while ( v42 );
v46 = (!v41 && !v42) - v41;
v47 = 0;
v48 = v46 == 0;
if ( v46 )
{
v49 = "odd";
v50 = 4LL;
v51 = v3;
do
{
if ( !v50 )
break;
v47 = *v51 < (unsigned int)*v49;
v48 = *v51++ == *v49++;
--v50;
}
while ( v48 );
result = 0LL;
if ( (!v47 && !v48) == v47 )
result = getPreDefBool(preDefTypeSymbols, v51);
}
else
{
result = getPreDefChar(preDefTypeSymbols, v45);
}
}
else
{
LABEL_45:
result = getPreDefInt(preDefTypeSymbols, v29);
}
}
else
{
LABEL_43:
result = getPreDefReal(preDefTypeSymbols, v8);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(const char **a1, __int64 a2)
{
__int64 result; // rax
const char *v3; // rdx
bool v4; // cf
bool v5; // zf
const char *v6; // rdi
__int64 v7; // rcx
const char *v8; // rsi
char v9; // al
bool v10; // cf
bool v11; // zf
const char *v12; // rdi
__int64 v13; // rcx
char v14; // al
bool v15; // cf
bool v16; // zf
const char *v17; // rdi
__int64 v18; // rcx
char v19; // al
bool v20; // cf
bool v21; // zf
const char *v22; // rdi
__int64 v23; // rcx
char v24; // al
bool v25; // cf
bool v26; // zf
const char *v27; // rdi
__int64 v28; // rcx
const char *v29; // rsi
char v30; // al
bool v31; // cf
bool v32; // zf
const char *v33; // rdi
__int64 v34; // rcx
char v35; // al
bool v36; // cf
bool v37; // zf
const char *v38; // rdi
__int64 v39; // rcx
char v40; // al
bool v41; // cf
bool v42; // zf
const char *v43; // rdi
__int64 v44; // rcx
const char *v45; // rsi
char v46; // al
bool v47; // cf
bool v48; // zf
const char *v49; // rdi
__int64 v50; // rcx
const char *v51; // rsi
void *retaddr; // [rsp+0h] [rbp+0h] BYREF

if ( !a1 )
return 0LL;
result = a2;
v3 = *a1;
if ( strcmp(*a1, "abs") && strcmp(v3, "sqr") && strcmp(v3, "succ") && strcmp(v3, "pred") )
{
v4 = (unsigned __int64)&retaddr < 8;
v5 = &retaddr == 0LL;
v6 = "sin";
v7 = 4LL;
v8 = v3;
do
{
if ( !v7 )
break;
v4 = *v8 < (unsigned int)*v6;
v5 = *v8++ == *v6++;
--v7;
}
while ( v5 );
v9 = (!v4 && !v5) - v4;
v10 = 0;
v11 = v9 == 0;
if ( !v9 )
goto LABEL_43;
v12 = "exp";
v13 = 4LL;
v8 = v3;
do
{
if ( !v13 )
break;
v10 = *v8 < (unsigned int)*v12;
v11 = *v8++ == *v12++;
--v13;
}
while ( v11 );
v14 = (!v10 && !v11) - v10;
v15 = 0;
v16 = v14 == 0;
if ( !v14 )
goto LABEL_43;
v17 = "ln";
v18 = 3LL;
v8 = v3;
do
{
if ( !v18 )
break;
v15 = *v8 < (unsigned int)*v17;
v16 = *v8++ == *v17++;
--v18;
}
while ( v16 );
v19 = (!v15 && !v16) - v15;
v20 = 0;
v21 = v19 == 0;
if ( !v19 )
goto LABEL_43;
v22 = "sqrt";
v23 = 5LL;
v8 = v3;
do
{
if ( !v23 )
break;
v20 = *v8 < (unsigned int)*v22;
v21 = *v8++ == *v22++;
--v23;
}
while ( v21 );
v24 = (!v20 && !v21) - v20;
v25 = 0;
v26 = v24 == 0;
if ( v24 )
{
v27 = "trunc";
v28 = 6LL;
v29 = v3;
do
{
if ( !v28 )
break;
v25 = *v29 < (unsigned int)*v27;
v26 = *v29++ == *v27++;
--v28;
}
while ( v26 );
v30 = (!v25 && !v26) - v25;
v31 = 0;
v32 = v30 == 0;
if ( !v30 )
goto LABEL_45;
v33 = "round";
v34 = 6LL;
v29 = v3;
do
{
if ( !v34 )
break;
v31 = *v29 < (unsigned int)*v33;
v32 = *v29++ == *v33++;
--v34;
}
while ( v32 );
v35 = (!v31 && !v32) - v31;
v36 = 0;
v37 = v35 == 0;
if ( !v35 )
goto LABEL_45;
v38 = "ord";
v39 = 4LL;
v29 = v3;
do
{
if ( !v39 )
break;
v36 = *v29 < (unsigned int)*v38;
v37 = *v29++ == *v38++;
--v39;
}
while ( v37 );
v40 = (!v36 && !v37) - v36;
v41 = 0;
v42 = v40 == 0;
if ( v40 )
{
v43 = "chr";
v44 = 4LL;
v45 = v3;
do
{
if ( !v44 )
break;
v41 = *v45 < (unsigned int)*v43;
v42 = *v45++ == *v43++;
--v44;
}
while ( v42 );
v46 = (!v41 && !v42) - v41;
v47 = 0;
v48 = v46 == 0;
if ( v46 )
{
v49 = "odd";
v50 = 4LL;
v51 = v3;
do
{
if ( !v50 )
break;
v47 = *v51 < (unsigned int)*v49;
v48 = *v51++ == *v49++;
--v50;
}
while ( v48 );
result = 0LL;
if ( (!v47 && !v48) == v47 )
result = getPreDefBool(preDefTypeSymbols, v51);
}
else
{
result = getPreDefChar(preDefTypeSymbols, v45);
}
}
else
{
LABEL_45:
result = getPreDefInt(preDefTypeSymbols, v29);
}
}
else
{
LABEL_43:
result = getPreDefReal(preDefTypeSymbols, v8);
}
}
return result;
}

original_code:
Symbol *getPreDefFuncReturnType(Symbol *s, Symbol *argTypeSym) {
 char *name = ((void *)0);
 if (!s) return ((void *)0);
 name = s->name;
 if (
     (strcmp(name, "abs") == 0) ||
     (strcmp(name, "sqr") == 0) ||
     (strcmp(name, "succ") == 0) ||
     (strcmp(name, "pred") == 0)
 ) {
  return argTypeSym;
 } else if (
     (strcmp(name, "sin") == 0) ||
     (strcmp(name, "exp") == 0) ||
     (strcmp(name, "ln") == 0) ||
     (strcmp(name, "sqrt") == 0)
 ) {
  return getPreDefReal(preDefTypeSymbols);
 } else if (
     (strcmp(name, "trunc") == 0) ||
     (strcmp(name, "round") == 0) ||
     (strcmp(name, "ord") == 0)
 ){
  return getPreDefInt(preDefTypeSymbols);
 } else if (
     (strcmp(name, "chr") == 0)
 ){
  return getPreDefChar(preDefTypeSymbols);
 } else if (
     (strcmp(name, "odd") == 0)
 ){
  return getPreDefBool(preDefTypeSymbols);
 }
 return ((void *)0);
}

canonical_original_code:
struct Symbol *getPreDefFuncReturnType(struct Symbol *s, struct Symbol *argTypeSym) {
 char *name = ((void *)0);
 if (!s) return ((void *)0);
 name = s->name;
 if (
     (strcmp(name, "abs") == 0) ||
     (strcmp(name, "sqr") == 0) ||
     (strcmp(name, "succ") == 0) ||
     (strcmp(name, "pred") == 0)
 ) {
  return argTypeSym;
 } else if (
     (strcmp(name, "sin") == 0) ||
     (strcmp(name, "exp") == 0) ||
     (strcmp(name, "ln") == 0) ||
     (strcmp(name, "sqrt") == 0)
 ) {
  return getPreDefReal(preDefTypeSymbols);
 } else if (
     (strcmp(name, "trunc") == 0) ||
     (strcmp(name, "round") == 0) ||
     (strcmp(name, "ord") == 0)
 ){
  return getPreDefInt(preDefTypeSymbols);
 } else if (
     (strcmp(name, "chr") == 0)
 ){
  return getPreDefChar(preDefTypeSymbols);
 } else if (
     (strcmp(name, "odd") == 0)
 ){
  return getPreDefBool(preDefTypeSymbols);
 }
 return ((void *)0);
}

variable_types:
argTypeSym
struct Symbol *

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


paramToVar

decompiled_code:
__int64 __fastcall paramToVar(_QWORD *a1)
{
__int64 v1; // rax
__int64 v2; // rbp

if ( !a1 )
return 0LL;
v1 = getTypeSym(a1);
v2 = newVariableSym(*a1, v1);
if ( v2 && (unsigned int)isByReference(a1) )
*(_DWORD *)(*(_QWORD *)(v2 + 16) + 8LL) = 1;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(_QWORD *a1)
{
__int64 v1; // rax
__int64 v2; // rbp

if ( !a1 )
return 0LL;
v1 = getTypeSym(a1);
v2 = newVariableSym(*a1, v1);
if ( v2 && (unsigned int)isByReference(a1) )
*(_DWORD *)(*(_QWORD *)(v2 + 16) + 8LL) = 1;
return v2;
}

original_code:
Symbol *
paramToVar(Symbol *param)
{
 Symbol *s = ((void *)0);
 if (!param) return ((void *)0);
 Symbol *typeSym = getTypeSym(param);
 s = newVariableSym(param->name, typeSym);
 if (!s) return ((void *)0);
 if (isByReference(param)) s->kindPtr.VarKind->byRef = 1;
 return s;
}

canonical_original_code:
struct Symbol *paramToVar(struct Symbol *param)
{
 struct Symbol *s = ((void *)0);
 if (!param) return ((void *)0);
 struct Symbol *typeSym = getTypeSym(param);
 s = newVariableSym(param->name, typeSym);
 if (!s) return ((void *)0);
 if (isByReference(param)) s->kindPtr.VarKind->byRef = 1;
 return s;
}

variable_types:
param
struct Symbol *

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }


isElementArraySimple

decompiled_code:
__int64 __fastcall isElementArraySimple(__int64 a1)
{
unsigned int v2; // ebx
__int64 v3; // rdi
int v4; // eax

if ( !*(_DWORD *)(a1 + 12) )
return 1LL;
v2 = 0;
while ( 1 )
{
v3 = getElementAt(a1, v2);
if ( *(_DWORD *)(v3 + 8) != 4 )
break;
v4 = getType(v3);
if ( (unsigned int)(v4 - 2) > 3 && v4 != 9 )
return 0LL;
if ( *(_DWORD *)(a1 + 12) <= ++v2 )
return 1LL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
unsigned int v2; // ebx
__int64 v3; // rdi
int v4; // eax

if ( !*(_DWORD *)(a1 + 12) )
return 1LL;
v2 = 0;
while ( 1 )
{
v3 = getElementAt(a1, v2);
if ( *(_DWORD *)(v3 + 8) != 4 )
break;
v4 = getType(v3);
if ( (unsigned int)(v4 - 2) > 3 && v4 != 9 )
return 0LL;
if ( *(_DWORD *)(a1 + 12) <= ++v2 )
return 1LL;
}
return 0LL;
}

original_code:
int isElementArraySimple(struct ElementArray *elementArray) {
 struct Symbol *symbol;
 type_t symbolsType;
 for (int i = 0; i < elementArray->nElements; ++i) {
  symbol = (struct Symbol *) getElementAt(elementArray, i);
  if ( symbol->kind != TYPE_KIND ) {
   return 0;
  }
  symbolsType = getType(symbol);
  if ( symbolsType != BOOLEAN_T
   && symbolsType != CHAR_T
   && symbolsType != INTEGER_T
   && symbolsType != REAL_T
   && symbolsType != STRING_T ) {
   return 0;
  }
 }
 return 1;
}

canonical_original_code:
int isElementArraySimple(struct ElementArray *elementArray) {
 struct Symbol *symbol;
 enum type_t symbolsType;
 for (int i = 0; i < elementArray->nElements; ++i) {
  symbol = (struct Symbol *) getElementAt(elementArray, i);
  if ( symbol->kind != TYPE_KIND ) {
   return 0;
  }
  symbolsType = getType(symbol);
  if ( symbolsType != BOOLEAN_T
   && symbolsType != CHAR_T
   && symbolsType != INTEGER_T
   && symbolsType != REAL_T
   && symbolsType != STRING_T ) {
   return 0;
  }
 }
 return 1;
}

variable_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


isArgTypeValidInIOFunc

decompiled_code:
_BOOL8 __fastcall isArgTypeValidInIOFunc(const char **a1, __int64 a2)
{
_BOOL8 result; // rax
const char *v3; // r13
int v4; // ebp
int v5; // er12
__int64 v6; // rax

if ( !a1 )
return 0LL;
result = 0LL;
if ( a2 )
{
v3 = *a1;
v4 = getType(a2);
v5 = *(_DWORD *)(a2 + 8);
if ( v4 == 1 )
{
v6 = getArrayBaseSym(a2);
if ( (unsigned int)getType(v6) == 3 )
v4 = 3;
}
if ( !strcmp(v3, "read") || !strcmp(v3, "readln") )
{
if ( v5 == 4 )
{
result = *(_DWORD *)(a2 + 40) != 0;
}
else
{
result = 0LL;
if ( v5 )
result = v4 == 9 || (unsigned int)(v4 - 3) <= 2;
}
}
else if ( !strcmp(v3, "writeln") || (result = 1LL, !strcmp(v3, "write")) )
{
result = v4 == 9 || (unsigned int)(v4 - 3) <= 2;
}
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func7(const char **a1, __int64 a2)
{
_BOOL8 result; // rax
const char *v3; // r13
int v4; // ebp
int v5; // er12
__int64 v6; // rax

if ( !a1 )
return 0LL;
result = 0LL;
if ( a2 )
{
v3 = *a1;
v4 = getType(a2);
v5 = *(_DWORD *)(a2 + 8);
if ( v4 == 1 )
{
v6 = getArrayBaseSym(a2);
if ( (unsigned int)getType(v6) == 3 )
v4 = 3;
}
if ( !strcmp(v3, "read") || !strcmp(v3, "readln") )
{
if ( v5 == 4 )
{
result = *(_DWORD *)(a2 + 40) != 0;
}
else
{
result = 0LL;
if ( v5 )
result = v4 == 9 || (unsigned int)(v4 - 3) <= 2;
}
}
else if ( !strcmp(v3, "writeln") || (result = 1LL, !strcmp(v3, "write")) )
{
result = v4 == 9 || (unsigned int)(v4 - 3) <= 2;
}
}
return result;
}

original_code:
int isArgTypeValidInIOFunc(Symbol *s, Symbol *arg) {
 char *name = ((void *)0);
 type_t type;
 type_t arrayBaseType;
 kind_t kind;
 if(!s || !arg) return 0;
 name = s->name;
 type = getType(arg);
 kind = arg->kind;
 if (type == ARRAY_T) {
   arrayBaseType = getType(getArrayBaseSym(arg));
   if (arrayBaseType == CHAR_T) {
    type = arrayBaseType;
   }
 }
 if ((strcmp(name, "read") == 0) ||
  (strcmp(name, "readln") == 0)
 ) {
  if (kind == TYPE_KIND) {
   if (!(arg->isAddress)) {
    return 0;
   }
  } else if (kind == CONST_KIND) {
    return 0;
  } else if ((type != CHAR_T) && (type != INTEGER_T) &&
     (type != REAL_T) && (type != STRING_T) )
       {
   return 0;
  }
 } else if ((strcmp(name, "writeln") == 0) ||
            (strcmp(name, "write") == 0 )
 ) {
  if( (type != CHAR_T) && (type != INTEGER_T) &&
      (type != REAL_T) && (type != STRING_T) ) {
   return 0;
  }
 }
 return 1;
}

canonical_original_code:
int isArgTypeValidInIOFunc(struct Symbol *s, struct Symbol *arg) {
 char *name = ((void *)0);
 enum type_t type;
 enum type_t arrayBaseType;
 enum kind_t kind;
 if(!s || !arg) return 0;
 name = s->name;
 type = getType(arg);
 kind = arg->kind;
 if (type == ARRAY_T) {
   arrayBaseType = getType(getArrayBaseSym(arg));
   if (arrayBaseType == CHAR_T) {
    type = arrayBaseType;
   }
 }
 if ((strcmp(name, "read") == 0) ||
  (strcmp(name, "readln") == 0)
 ) {
  if (kind == TYPE_KIND) {
   if (!(arg->isAddress)) {
    return 0;
   }
  } else if (kind == CONST_KIND) {
    return 0;
  } else if ((type != CHAR_T) && (type != INTEGER_T) &&
     (type != REAL_T) && (type != STRING_T) )
       {
   return 0;
  }
 } else if ((strcmp(name, "writeln") == 0) ||
            (strcmp(name, "write") == 0 )
 ) {
  if( (type != CHAR_T) && (type != INTEGER_T) &&
      (type != REAL_T) && (type != STRING_T) ) {
   return 0;
  }
 }
 return 1;
}

variable_types:
arg
struct Symbol *

variable_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


isValidIOProcInvocation

decompiled_code:
_BOOL8 __fastcall isValidIOProcInvocation(const char **a1, __int64 a2)
{
int v2; // er14
int v3; // er15
unsigned int i; // ebp
__int64 v5; // rbx
const char *v6; // r15
const char *v7; // rax
__int64 v8; // rax
unsigned int v10; // [rsp+Ch] [rbp-3Ch]

v2 = *(_DWORD *)(a2 + 12);
if ( v2 <= 0 )
{
v3 = 1;
}
else
{
v3 = 1;
for ( i = 0; i != v2; ++i )
{
v5 = *(_QWORD *)getElementAt(a2, i);
v10 = getType(v5);
if ( !isArgTypeValidInIOFunc(a1, v5) )
{
v6 = *a1;
v7 = (const char *)typeToString(v10);
v8 = customErrorString("Invalid argument of type %s passed to procedure %s.", v7, v6);
recordError(v8, yylineno, colno, 2LL);
v3 = 0;
}
}
}
return v3 != 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func8(const char **a1, __int64 a2)
{
int v2; // er14
int v3; // er15
unsigned int i; // ebp
__int64 v5; // rbx
const char *v6; // r15
const char *v7; // rax
__int64 v8; // rax
unsigned int v10; // [rsp+Ch] [rbp-3Ch]

v2 = *(_DWORD *)(a2 + 12);
if ( v2 <= 0 )
{
v3 = 1;
}
else
{
v3 = 1;
for ( i = 0; i != v2; ++i )
{
v5 = *(_QWORD *)getElementAt(a2, i);
v10 = getType(v5);
if ( !func7(a1, v5) )
{
v6 = *a1;
v7 = (const char *)typeToString(v10);
v8 = customErrorString("Invalid argument of type %s passed to procedure %s.", v7, v6);
recordError(v8, yylineno, colno, 2LL);
v3 = 0;
}
}
}
return v3 != 0;
}

original_code:
int
isValidIOProcInvocation(Symbol *s, struct ElementArray *ea)
{
 Symbol *param = ((void *)0);
 type_t type;
 int i, nArgs, valid = 1;
 nArgs = ea->nElements;
 for (i = 0; i < nArgs; i++) {
  param = ((struct treeNode *)getElementAt(ea, i))->symbol;
  type = getType(param);
  if (!isArgTypeValidInIOFunc(s, param)) {
   errMsg = customErrorString("Invalid argument "
       "of type %s passed to procedure %s.",
       typeToString(type), s->name);
   recordError(errMsg, yylineno, colno, SEMANTIC);
   valid = 0;
  }
 }
 if (!valid) return 0;
 return 1;
}

canonical_original_code:
int isValidIOProcInvocation(struct Symbol *s, struct ElementArray *ea)
{
 struct Symbol *param = ((void *)0);
 enum type_t type;
 int i; int nArgs; int valid = 1;
 nArgs = ea->nElements;
 for (i = 0; i < nArgs; i++) {
  param = ((struct treeNode *)getElementAt(ea, i))->symbol;
  type = getType(param);
  if (!isArgTypeValidInIOFunc(s, param)) {
   errMsg = customErrorString("Invalid argument "
       "of type %s passed to procedure %s.",
       typeToString(type), s->name);
   recordError(errMsg, yylineno, colno, SEMANTIC);
   valid = 0;
  }
 }
 if (!valid) return 0;
 return 1;
}

variable_types: nArgs int

variable_types: valid int

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct treeNode { struct Symbol *symbol; int opToken; struct treeNode *parent; struct treeNode *left; struct treeNode *right; }

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }


isArgTypeValidInPreDefFunc

decompiled_code:
_BOOL8 __fastcall isArgTypeValidInPreDefFunc(const char **a1, __int64 a2)
{
_BOOL8 result; // rax
const char *v3; // r12
unsigned int v4; // ebp
int v5; // edx
int v6; // edx
int v7; // edx

if ( !a1 )
return 0LL;
result = 0LL;
if ( a2 )
{
v3 = *a1;
v4 = getType(a2);
if ( !strcmp(v3, "abs")
|| !strcmp(v3, "sqr")
|| !strcmp(v3, "sin")
|| !strcmp(v3, "exp")
|| !strcmp(v3, "ln")
|| !strcmp(v3, "sqrt") )
{
result = v4 - 4 <= 1;
}
else if ( !strcmp(v3, "trunc") || !strcmp(v3, "round") )
{
result = v4 - 4 <= 1;
}
else if ( !strcmp(v3, "chr") || !strcmp(v3, "odd") )
{
result = v4 == 4;
}
else if ( !strcmp(v3, "ord") || !strcmp(v3, "succ") || (v5 = strcmp(v3, "pred"), result = 0LL, !v5) )
{
v6 = isScalarMember(a2);
result = 1LL;
if ( !v6 )
{
v7 = isScalarVar(a2);
result = 1LL;
if ( !v7 )
result = (unsigned int)isOrdinal(v4) != 0;
}
}
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func9(const char **a1, __int64 a2)
{
_BOOL8 result; // rax
const char *v3; // r12
unsigned int v4; // ebp
int v5; // edx
int v6; // edx
int v7; // edx

if ( !a1 )
return 0LL;
result = 0LL;
if ( a2 )
{
v3 = *a1;
v4 = getType(a2);
if ( !strcmp(v3, "abs")
|| !strcmp(v3, "sqr")
|| !strcmp(v3, "sin")
|| !strcmp(v3, "exp")
|| !strcmp(v3, "ln")
|| !strcmp(v3, "sqrt") )
{
result = v4 - 4 <= 1;
}
else if ( !strcmp(v3, "trunc") || !strcmp(v3, "round") )
{
result = v4 - 4 <= 1;
}
else if ( !strcmp(v3, "chr") || !strcmp(v3, "odd") )
{
result = v4 == 4;
}
else if ( !strcmp(v3, "ord") || !strcmp(v3, "succ") || (v5 = strcmp(v3, "pred"), result = 0LL, !v5) )
{
v6 = isScalarMember(a2);
result = 1LL;
if ( !v6 )
{
v7 = isScalarVar(a2);
result = 1LL;
if ( !v7 )
result = (unsigned int)isOrdinal(v4) != 0;
}
}
}
return result;
}

original_code:
int isArgTypeValidInPreDefFunc(Symbol *s, Symbol *arg) {
 char *name = ((void *)0);
 type_t type;
 if (!s || !arg) return 0;
 name = s->name;
 type = getType(arg);
 if (
     (strcmp(name, "abs") == 0) ||
     (strcmp(name, "sqr") == 0) ||
     (strcmp(name, "sin") == 0) ||
     (strcmp(name, "exp") == 0) ||
     (strcmp(name, "ln") == 0) ||
     (strcmp(name, "sqrt") == 0)
 ) {
  if ((type == INTEGER_T) || (type == REAL_T)) {
   return 1;
  }
 } else if (
     (strcmp(name, "trunc") == 0) ||
     (strcmp(name, "round") == 0)
 ){
  if (type == REAL_T || type == INTEGER_T) return 1;
 } else if (
     (strcmp(name, "chr") == 0) ||
     (strcmp(name, "odd") == 0)
 ){
  if (type == INTEGER_T) return 1;
 } else if (
     (strcmp(name, "ord") == 0) ||
     (strcmp(name, "succ") == 0) ||
     (strcmp(name, "pred") == 0)
 ){
  if (isScalarMember(arg)) return 1;
  if (isScalarVar(arg)) return 1;
  if (isOrdinal(type)) return 1;
 }
 return 0;
}

canonical_original_code:
int isArgTypeValidInPreDefFunc(struct Symbol *s, struct Symbol *arg) {
 char *name = ((void *)0);
 enum type_t type;
 if (!s || !arg) return 0;
 name = s->name;
 type = getType(arg);
 if (
     (strcmp(name, "abs") == 0) ||
     (strcmp(name, "sqr") == 0) ||
     (strcmp(name, "sin") == 0) ||
     (strcmp(name, "exp") == 0) ||
     (strcmp(name, "ln") == 0) ||
     (strcmp(name, "sqrt") == 0)
 ) {
  if ((type == INTEGER_T) || (type == REAL_T)) {
   return 1;
  }
 } else if (
     (strcmp(name, "trunc") == 0) ||
     (strcmp(name, "round") == 0)
 ){
  if (type == REAL_T || type == INTEGER_T) return 1;
 } else if (
     (strcmp(name, "chr") == 0) ||
     (strcmp(name, "odd") == 0)
 ){
  if (type == INTEGER_T) return 1;
 } else if (
     (strcmp(name, "ord") == 0) ||
     (strcmp(name, "succ") == 0) ||
     (strcmp(name, "pred") == 0)
 ){
  if (isScalarMember(arg)) return 1;
  if (isScalarVar(arg)) return 1;
  if (isOrdinal(type)) return 1;
 }
 return 0;
}

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


isValidPreDefFuncInvocation

decompiled_code:
__int64 __fastcall isValidPreDefFuncInvocation(const char **a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // r12
__int64 v4; // rbp
__int64 result; // rax
__int64 v6; // rax
unsigned int v7; // eax
const char *v8; // rax
__int64 v9; // rax

v2 = *(unsigned int *)(a2 + 12);
if ( (_DWORD)v2 == 1 )
{
v3 = *(_QWORD *)getElementAt(a2, 0LL);
v4 = getTypeSym(v3);
if ( isArgTypeValidInPreDefFunc(a1, v3) )
{
result = getPreDefFuncReturnType(a1, v4);
}
else
{
v7 = getType(v4);
v8 = (const char *)typeToString(v7);
v9 = customErrorString("Function %s cannot be called with argument of type %s.", *a1, v8);
recordError(v9, yylineno, colno, 2LL);
result = 0LL;
}
}
else
{
v6 = customErrorString("Function %s expected 1 argument but %d given.", *a1, v2);
recordError(v6, yylineno, colno, 2LL);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(const char **a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // r12
__int64 v4; // rbp
__int64 result; // rax
__int64 v6; // rax
unsigned int v7; // eax
const char *v8; // rax
__int64 v9; // rax

v2 = *(unsigned int *)(a2 + 12);
if ( (_DWORD)v2 == 1 )
{
v3 = *(_QWORD *)getElementAt(a2, 0LL);
v4 = getTypeSym(v3);
if ( func9(a1, v3) )
{
result = func4(a1, v4);
}
else
{
v7 = getType(v4);
v8 = (const char *)typeToString(v7);
v9 = customErrorString("Function %s cannot be called with argument of type %s.", *a1, v8);
recordError(v9, yylineno, colno, 2LL);
result = 0LL;
}
}
else
{
v6 = customErrorString("Function %s expected 1 argument but %d given.", *a1, v2);
recordError(v6, yylineno, colno, 2LL);
result = 0LL;
}
return result;
}

original_code:
ProxySymbol *isValidPreDefFuncInvocation(Symbol *s, struct ElementArray *ea)
{
 Symbol *param = ((void *)0);
 Symbol * type;
 int i = 0;
 int nArgs = 0;
 nArgs = ea->nElements;
 if (nArgs != 1) {
  errMsg = customErrorString("Function %s expected "
      "1 argument but %d given.", s->name, nArgs);
  recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 param = ((struct treeNode *)getElementAt(ea, i))->symbol;
 type = getTypeSym(param);
 if (isArgTypeValidInPreDefFunc(s, param)) {
  return getPreDefFuncReturnType(s, type);
 } else {
  errMsg = customErrorString("Function %s cannot be "
      "called with argument of type %s.", s->name,
      typeToString(getType(type)));
  recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
}

canonical_original_code:
struct Symbol *isValidPreDefFuncInvocation(struct Symbol *s, struct ElementArray *ea)
{
 struct Symbol *param = ((void *)0);
 struct Symbol *type;
 int i = 0;
 int nArgs = 0;
 nArgs = ea->nElements;
 if (nArgs != 1) {
  errMsg = customErrorString("Function %s expected "
      "1 argument but %d given.", s->name, nArgs);
  recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
 param = ((struct treeNode *)getElementAt(ea, i))->symbol;
 type = getTypeSym(param);
 if (isArgTypeValidInPreDefFunc(s, param)) {
  return getPreDefFuncReturnType(s, type);
 } else {
  errMsg = customErrorString("Function %s cannot be "
      "called with argument of type %s.", s->name,
      typeToString(getType(type)));
  recordError(errMsg, yylineno, colno, SEMANTIC);
  return 0;
 }
}

user_defined_types: struct treeNode { struct Symbol *symbol; int opToken; struct treeNode *parent; struct treeNode *left; struct treeNode *right; }

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


getArrayIndexSym

decompiled_code:
__int64 __fastcall getArrayIndexSym(__int64 a1)
{
int v1; // edx
__int64 result; // rax

if ( !a1 )
return 0LL;
v1 = getType();
result = 0LL;
if ( v1 == 1 )
result = *(_QWORD *)(*(_QWORD *)getTypePtr(a1) + 8LL);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
int v1; // edx
__int64 result; // rax

if ( !a1 )
return 0LL;
v1 = getType();
result = 0LL;
if ( v1 == 1 )
result = *(_QWORD *)(*(_QWORD *)getTypePtr(a1) + 8LL);
return result;
}

original_code:
Symbol *getArrayIndexSym(Symbol *s)
{
 if (!s) return ((void *)0);
 if (getType(s) != ARRAY_T) return ((void *)0);
 return getTypePtr(s)->Array->indexTypeSym;
}

canonical_original_code:
struct Symbol *getArrayIndexSym(struct Symbol *s)
{
 if (!s) return ((void *)0);
 if (getType(s) != ARRAY_T) return ((void *)0);
 return getTypePtr(s)->Array->indexTypeSym;
}

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }


getArrayDim

decompiled_code:
__int64 __fastcall getArrayDim(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rdi
unsigned int v3; // ebx

v1 = getArrayIndexSym(a1);
if ( !v1 )
return 0;
v2 = v1;
v3 = 0;
do
{
++v3;
v2 = getArrayIndexSym(v2);
}
while ( v2 );
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rdi
unsigned int v3; // ebx

v1 = func0(a1);
if ( !v1 )
return 0;
v2 = v1;
v3 = 0;
do
{
++v3;
v2 = func0(v2);
}
while ( v2 );
return v3;
}

original_code:
int getArrayDim(Symbol *s)
{
 Symbol *nextIndexSym = ((void *)0);
 int dim = 0;
 nextIndexSym = getArrayIndexSym(s);
 while (nextIndexSym != ((void *)0)) {
  dim++;
  nextIndexSym = getArrayIndexSym(nextIndexSym);
 }
 return dim;
}

canonical_original_code:
int getArrayDim(struct Symbol *s)
{
 struct Symbol *nextIndexSym = ((void *)0);
 int dim = 0;
 nextIndexSym = getArrayIndexSym(s);
 while (nextIndexSym != ((void *)0)) {
  dim++;
  nextIndexSym = getArrayIndexSym(nextIndexSym);
 }
 return dim;
}

variable_types: dim int

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


getArrayTerminalTypeSym

decompiled_code:
__int64 __fastcall getArrayTerminalTypeSym(__int64 a1)
{
__int64 i; // rbx

if ( !a1 )
return 0LL;
i = 0LL;
if ( (unsigned int)((__int64 (*)(void))getType)() == 1 )
{
for ( i = **(_QWORD **)getTypePtr(a1); (unsigned int)getType(i) == 1; i = **(_QWORD **)getTypePtr(i) )
;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
__int64 i; // rbx

if ( !a1 )
return 0LL;
i = 0LL;
if ( (unsigned int)((__int64 (*)(void))getType)() == 1 )
{
for ( i = **(_QWORD **)getTypePtr(a1); (unsigned int)getType(i) == 1; i = **(_QWORD **)getTypePtr(i) )
;
}
return i;
}

original_code:
Symbol *getArrayTerminalTypeSym(Symbol *s)
{
 Symbol *baseSym = ((void *)0);
 if (!s) return ((void *)0);
 if (getType(s) != ARRAY_T) return ((void *)0);
 baseSym = getTypePtr(s)->Array->baseTypeSym;
 while (getType(baseSym) == ARRAY_T) {
  baseSym = getTypePtr(baseSym)->Array->baseTypeSym;
 }
 return baseSym;
}

canonical_original_code:
struct Symbol *getArrayTerminalTypeSym(struct Symbol *s)
{
 struct Symbol *baseSym = ((void *)0);
 if (!s) return ((void *)0);
 if (getType(s) != ARRAY_T) return ((void *)0);
 baseSym = getTypePtr(s)->Array->baseTypeSym;
 while (getType(baseSym) == ARRAY_T) {
  baseSym = getTypePtr(baseSym)->Array->baseTypeSym;
 }
 return baseSym;
}

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


getArrayBaseSym

decompiled_code:
__int64 __fastcall getArrayBaseSym(__int64 a1)
{
int v1; // edx
__int64 result; // rax
__int64 v3; // rax

if ( !a1 )
return 0LL;
v1 = getType(a1);
result = 0LL;
if ( v1 == 1 )
{
v3 = getTypeSym(a1);
result = **(_QWORD **)getTypePtr(v3);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
int v1; // edx
__int64 result; // rax
__int64 v3; // rax

if ( !a1 )
return 0LL;
v1 = getType(a1);
result = 0LL;
if ( v1 == 1 )
{
v3 = getTypeSym(a1);
result = **(_QWORD **)getTypePtr(v3);
}
return result;
}

original_code:
Symbol *getArrayBaseSym(Symbol *s)
{
 if (!s) return ((void *)0);
 if (getType(s) != ARRAY_T) return ((void *)0);
 return getTypePtr(getTypeSym((s)))->Array->baseTypeSym;
}

canonical_original_code:
struct Symbol *getArrayBaseSym(struct Symbol *s)
{
 if (!s) return ((void *)0);
 if (getType(s) != ARRAY_T) return ((void *)0);
 return getTypePtr(getTypeSym((s)))->Array->baseTypeSym;
}

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }


isValidArrayAccess

decompiled_code:
__int64 __fastcall isValidArrayAccess(__int64 a1, const char **a2)
{
const char **v2; // r12
__int64 v3; // rbx
__int64 v4; // rbp
unsigned int v5; // eax
const char *v6; // rax
__int64 v7; // rax
__int64 result; // rax
int v9; // eax
__int64 v10; // rax
__int64 v11; // r13
__int64 v12; // rax
unsigned int v13; // eax
const char *v14; // rbx
unsigned int v15; // eax
const char *v16; // rax
__int64 v17; // rax

if ( !a1 || (v2 = a2) == 0LL )
err(1, "Tried to do array access with NULL args.");
v3 = getTypeSym(a1);
if ( (unsigned int)getType(v3) == 1 )
{
v4 = getArrayIndexSym(v3);
while ( (unsigned int)getType(v3) == 1 )
{
v9 = getType(v4);
if ( v9 == 8 )
{
if ( !(unsigned int)isConstInScalar(v2, v4) )
goto LABEL_15;
}
else if ( v9 == 10 )
{
v11 = getTypeSym(v2);
v12 = getSubrangeBaseTypeSym(v4);
if ( !(unsigned int)areSameType(v12, v11) )
{
LABEL_15:
v13 = getType(v2);
v14 = (const char *)typeToString(v13);
v15 = getType(v4);
v16 = (const char *)typeToString(v15);
v17 = customErrorString("Invalid array subscript. Expected type %s but got %s", v16, v14);
recordError(v17, yylineno, colno, 2LL);
return 0LL;
}
}
else
{
v10 = getTypeSym(v2);
if ( !(unsigned int)areSameType(v4, v10) )
goto LABEL_15;
}
v3 = getArrayBaseSym(v3);
v4 = getArrayIndexSym(v3);
v2 = (const char **)v2[6];
if ( !v2 )
goto LABEL_18;
}
if ( v2 )
{
recordError("Illegal array access -- too many indices.", yylineno, colno, 2LL);
result = 0LL;
}
else
{
LABEL_18:
result = newProxySymFromSym(v3);
*(_DWORD *)(result + 40) = 1;
}
}
else
{
v5 = getType(v3);
v6 = (const char *)typeToString(v5);
v7 = customErrorString("Tried to index into %s, which is of type %s, and not an array type.", *a2, v6);
recordError(v7, yylineno, colno, 2LL);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, const char **a2)
{
const char **v2; // r12
__int64 v3; // rbx
__int64 v4; // rbp
unsigned int v5; // eax
const char *v6; // rax
__int64 v7; // rax
__int64 result; // rax
int v9; // eax
__int64 v10; // rax
__int64 v11; // r13
__int64 v12; // rax
unsigned int v13; // eax
const char *v14; // rbx
unsigned int v15; // eax
const char *v16; // rax
__int64 v17; // rax

if ( !a1 || (v2 = a2) == 0LL )
err(1, "Tried to do array access with NULL args.");
v3 = getTypeSym(a1);
if ( (unsigned int)getType(v3) == 1 )
{
v4 = func0(v3);
while ( (unsigned int)getType(v3) == 1 )
{
v9 = getType(v4);
if ( v9 == 8 )
{
if ( !(unsigned int)isConstInScalar(v2, v4) )
goto LABEL_15;
}
else if ( v9 == 10 )
{
v11 = getTypeSym(v2);
v12 = getSubrangeBaseTypeSym(v4);
if ( !(unsigned int)areSameType(v12, v11) )
{
LABEL_15:
v13 = getType(v2);
v14 = (const char *)typeToString(v13);
v15 = getType(v4);
v16 = (const char *)typeToString(v15);
v17 = customErrorString("Invalid array subscript. Expected type %s but got %s", v16, v14);
recordError(v17, yylineno, colno, 2LL);
return 0LL;
}
}
else
{
v10 = getTypeSym(v2);
if ( !(unsigned int)areSameType(v4, v10) )
goto LABEL_15;
}
v3 = func3(v3);
v4 = func0(v3);
v2 = (const char **)v2[6];
if ( !v2 )
goto LABEL_18;
}
if ( v2 )
{
recordError("Illegal array access -- too many indices.", yylineno, colno, 2LL);
result = 0LL;
}
else
{
LABEL_18:
result = newProxySymFromSym(v3);
*(_DWORD *)(result + 40) = 1;
}
}
else
{
v5 = getType(v3);
v6 = (const char *)typeToString(v5);
v7 = customErrorString("Tried to index into %s, which is of type %s, and not an array type.", *a2, v6);
recordError(v7, yylineno, colno, 2LL);
result = 0LL;
}
return result;
}

original_code:
Symbol *isValidArrayAccess(ProxySymbol *var, ProxySymbol *indices) {
 Symbol *arrayTypeSym = ((void *)0);
 Symbol *indexTypeSym = ((void *)0);
 Symbol *returnTypeSym = ((void *)0);
 Symbol *arg = indices;
 int typeErr = 0;
 if ((var == ((void *)0))||(indices == ((void *)0))) {
  err(1, "Tried to do array access with NULL args.");
 }
 arrayTypeSym = getTypeSym(var);
 if (getType(arrayTypeSym) != ARRAY_T) {
  errMsg = customErrorString("Tried to index into %s, which is "
      "of type %s, and not an array type.",
      arg->name,
      typeToString(getType(arrayTypeSym)));
  recordError(errMsg, yylineno, colno, SEMANTIC);
  return ((void *)0);
 }
 indexTypeSym = getArrayIndexSym(arrayTypeSym);
 while ( (arg) && (getType(arrayTypeSym) == ARRAY_T)) {
  switch (getType(indexTypeSym)) {
  case SCALAR_T:
   if (!isConstInScalar(arg, indexTypeSym))
       typeErr = 1;
   break;
  case SUBRANGE_T:
   if (!areSameType(
       getSubrangeBaseTypeSym(indexTypeSym),
       getTypeSym(arg))) typeErr = 1;
   break;
  default:
   if (!areSameType(indexTypeSym,
        getTypeSym(arg))) typeErr = 1;
   break;
  }
  if (typeErr) {
   errMsg = customErrorString("Invalid array "
       "subscript.  Expected type %s "
       "but got %s",
           typeToString(getType(indexTypeSym)),
           typeToString(getType(arg)));
   recordError(errMsg, yylineno, colno, SEMANTIC);
   return ((void *)0);
  }
  typeErr = 0;
  arrayTypeSym = getArrayBaseSym(arrayTypeSym);
  indexTypeSym = getArrayIndexSym(arrayTypeSym);
  arg = arg->next;
 }
 if (arg) {
  recordError("Illegal array access -- too many indices.",
      yylineno, colno, SEMANTIC);
  return ((void *)0);
 }
 returnTypeSym = newProxySymFromSym(arrayTypeSym);
 returnTypeSym->isAddress = 1;
 return returnTypeSym;
}

canonical_original_code:
struct Symbol *isValidArrayAccess(struct Symbol *var, struct Symbol *indices) {
 struct Symbol *arrayTypeSym = ((void *)0);
 struct Symbol *indexTypeSym = ((void *)0);
 struct Symbol *returnTypeSym = ((void *)0);
 struct Symbol *arg = indices;
 int typeErr = 0;
 if ((var == ((void *)0))||(indices == ((void *)0))) {
  err(1, "Tried to do array access with NULL args.");
 }
 arrayTypeSym = getTypeSym(var);
 if (getType(arrayTypeSym) != ARRAY_T) {
  errMsg = customErrorString("Tried to index into %s, which is "
      "of type %s, and not an array type.",
      arg->name,
      typeToString(getType(arrayTypeSym)));
  recordError(errMsg, yylineno, colno, SEMANTIC);
  return ((void *)0);
 }
 indexTypeSym = getArrayIndexSym(arrayTypeSym);
 while ( (arg) && (getType(arrayTypeSym) == ARRAY_T)) {
  switch (getType(indexTypeSym)) {
  case SCALAR_T:
   if (!isConstInScalar(arg, indexTypeSym))
       typeErr = 1;
   break;
  case SUBRANGE_T:
   if (!areSameType(
       getSubrangeBaseTypeSym(indexTypeSym),
       getTypeSym(arg))) typeErr = 1;
   break;
  default:
   if (!areSameType(indexTypeSym,
        getTypeSym(arg))) typeErr = 1;
   break;
  }
  if (typeErr) {
   errMsg = customErrorString("Invalid array "
       "subscript.  Expected type %s "
       "but got %s",
           typeToString(getType(indexTypeSym)),
           typeToString(getType(arg)));
   recordError(errMsg, yylineno, colno, SEMANTIC);
   return ((void *)0);
  }
  typeErr = 0;
  arrayTypeSym = getArrayBaseSym(arrayTypeSym);
  indexTypeSym = getArrayIndexSym(arrayTypeSym);
  arg = arg->next;
 }
 if (arg) {
  recordError("Illegal array access -- too many indices.",
      yylineno, colno, SEMANTIC);
  return ((void *)0);
 }
 returnTypeSym = newProxySymFromSym(arrayTypeSym);
 returnTypeSym->isAddress = 1;
 return returnTypeSym;
}

variable_types:
var
struct Symbol *

variable_types:
indices
struct Symbol *

variable_types: typeErr int

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


getArrayHighIndexValue

decompiled_code:
__int64 __fastcall getArrayHighIndexValue(__int64 a1)
{
__int64 v1; // rbx
__int64 result; // rax

v1 = *(_QWORD *)(*(_QWORD *)getTypePtr(a1) + 8LL);
if ( (unsigned int)getType(v1) == 10 )
result = **(unsigned int **)getTypePtr(v1);
else
result = (unsigned int)(*(_DWORD *)(**(_QWORD **)getTypePtr(v1) + 12LL) - 1);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 v1; // rbx
__int64 result; // rax

v1 = *(_QWORD *)(*(_QWORD *)getTypePtr(a1) + 8LL);
if ( (unsigned int)getType(v1) == 10 )
result = **(unsigned int **)getTypePtr(v1);
else
result = (unsigned int)(*(_DWORD *)(**(_QWORD **)getTypePtr(v1) + 12LL) - 1);
return result;
}

original_code:
int getArrayHighIndexValue(Symbol *arrayType)
{
 Symbol *indexType = ((void *)0);
 indexType = getTypePtr(arrayType)->Array->indexTypeSym;
 if (getType(indexType) == SUBRANGE_T) {
  return getTypePtr(indexType)->Subrange->high;
 } else return ((getTypePtr(indexType)->Scalar->consts->nElements) - 1);
}

canonical_original_code:
int getArrayHighIndexValue(struct Symbol *arrayType)
{
 struct Symbol *indexType = ((void *)0);
 indexType = getTypePtr(arrayType)->Array->indexTypeSym;
 if (getType(indexType) == SUBRANGE_T) {
  return getTypePtr(indexType)->Subrange->high;
 } else return ((getTypePtr(indexType)->Scalar->consts->nElements) - 1);
}

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


getArrayLowIndexValue

decompiled_code:
__int64 __fastcall getArrayLowIndexValue(__int64 a1)
{
__int64 v1; // rbx
int v2; // edx
__int64 result; // rax

if ( !a1 )
{
fwrite("Trying to get low index value of a NULL symbol.\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
if ( (unsigned int)getType(a1) != 1 )
{
fwrite("Trying to low index value of a symbol which is not an array\n", 1uLL, 0x3CuLL, stderr);
exit(1);
}
v1 = *(_QWORD *)(*(_QWORD *)getTypePtr(a1) + 8LL);
v2 = getType(v1);
result = 0LL;
if ( v2 == 10 )
result = *(unsigned int *)(*(_QWORD *)getTypePtr(v1) + 4LL);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
__int64 v1; // rbx
int v2; // edx
__int64 result; // rax

if ( !a1 )
{
fwrite("Trying to get low index value of a NULL symbol.\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
if ( (unsigned int)getType(a1) != 1 )
{
fwrite("Trying to low index value of a symbol which is not an array\n", 1uLL, 0x3CuLL, stderr);
exit(1);
}
v1 = *(_QWORD *)(*(_QWORD *)getTypePtr(a1) + 8LL);
v2 = getType(v1);
result = 0LL;
if ( v2 == 10 )
result = *(unsigned int *)(*(_QWORD *)getTypePtr(v1) + 4LL);
return result;
}

original_code:
int getArrayLowIndexValue(Symbol *arrayType)
{
 Symbol *indexType = ((void *)0);
 if (!arrayType) {
  fprintf(stderr, "Trying to get low index value of a NULL symbol"
      ".\n");
  exit(1);
 }
 if (getType(arrayType) != ARRAY_T) {
  fprintf(stderr, "Trying to low index value of a symbol which is"
      " not an array\n");
  exit(1);
 }
 indexType = getTypePtr(arrayType)->Array->indexTypeSym;
 if (getType(indexType) == SUBRANGE_T) {
  return getTypePtr(indexType)->Subrange->low;
 } else return 0;
}

canonical_original_code:
int getArrayLowIndexValue(struct Symbol *arrayType)
{
 struct Symbol *indexType = ((void *)0);
 if (!arrayType) {
  fprintf(stderr, "Trying to get low index value of a NULL symbol"
      ".\n");
  exit(1);
 }
 if (getType(arrayType) != ARRAY_T) {
  fprintf(stderr, "Trying to low index value of a symbol which is"
      " not an array\n");
  exit(1);
 }
 indexType = getTypePtr(arrayType)->Array->indexTypeSym;
 if (getType(indexType) == SUBRANGE_T) {
  return getTypePtr(indexType)->Subrange->low;
 } else return 0;
}

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }


getArrayLength

decompiled_code:
__int64 __fastcall getArrayLength(__int64 a1)
{
int v1; // ebx

v1 = getArrayHighIndexValue(a1);
return v1 - (unsigned int)getArrayLowIndexValue(a1) + 1;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
int v1; // ebx

v1 = func5(a1);
return v1 - (unsigned int)func6(a1) + 1;
}

original_code:
int getArrayLength(Symbol *s)
{
 return (getArrayHighIndexValue(s) - getArrayLowIndexValue(s))+1;
}

canonical_original_code:
int getArrayLength(struct Symbol *s)
{
 return (getArrayHighIndexValue(s) - getArrayLowIndexValue(s))+1;
}

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


createConstSymbol

decompiled_code:
__int64 __fastcall createConstSymbol(__int64 a1)
{
return createSymbol(symbolTable, a1, 0LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return createSymbol(symbolTable, a1, 0LL, 0LL);
}

canonical_original_code:
struct Symbol *createConstSymbol(char *id) {
 return createSymbol(symbolTable, id, CONST_KIND, 0);
}

variable_types:
id
char *

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


createFuncSymbol

decompiled_code:
__int64 __fastcall createFuncSymbol(__int64 a1)
{
return createSymbol(symbolTable, a1, 1LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return createSymbol(symbolTable, a1, 1LL, 0LL);
}

canonical_original_code:
struct Symbol *createFuncSymbol(char *id) {
 return createSymbol(symbolTable, id, FUNC_KIND, 0);
}

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }


createParamSymbol

decompiled_code:
__int64 __fastcall createParamSymbol(__int64 a1)
{
return createSymbol(symbolTable, a1, 2LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return createSymbol(symbolTable, a1, 2LL, 0LL);
}

canonical_original_code:
struct Symbol *createParamSymbol(char *id) {
 return createSymbol(symbolTable, id, PARAM_KIND, 0);
}

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }


createProcSymbol

decompiled_code:
__int64 __fastcall createProcSymbol(__int64 a1)
{
return createSymbol(symbolTable, a1, 3LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
return createSymbol(symbolTable, a1, 3LL, 0LL);
}

canonical_original_code:
struct Symbol *createProcSymbol(char *id) {
 return createSymbol(symbolTable, id, PROC_KIND, 0);
}

user_defined_types: struct Symbol { char *name; enum kind_t kind; union kind_union kindPtr; int lvl; int typeOriginator; int offset; int size; int isAddress; int isRecordHead; struct Symbol *next; }

user_defined_types: struct ParamKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct TypeKind { union type_union typePtr; enum type_t type; }

user_defined_types: union anonymous_constant_value { struct Boolean Boolean; struct Char Char; struct Integer Integer; struct Real Real; struct String String; }

user_defined_types: union type_union { struct Array *Array; struct Function *Function; struct Procedure *Procedure; struct Record *Record; struct Scalar *Scalar; struct StringType *String; struct Subrange *Subrange; }

user_defined_types: enum type_t { VOID_T=0, ARRAY_T=1, BOOLEAN_T=2, CHAR_T=3, INTEGER_T=4, REAL_T=5, RECORD_T=6, SCALARINT_T=7, SCALAR_T=8, STRING_T=9, SUBRANGE_T=10 }

user_defined_types: struct hash { struct hashElement *elements[1000]; int offset[1024]; unsigned int (*hashFunction)(); int lexLevel; }

user_defined_types: struct Param { char *name; enum type_t type; struct Symbol *typeSym; }


createVarSymbol

decompiled_code:
__int64 __fastcall createVarSymbol(__int64 a1)
{
return createSymbol(symbolTable, a1, 5LL, 0LL);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
return createSymbol(symbolTable, a1, 5LL, 0LL);
}

canonical_original_code:
struct Symbol *createVarSymbol(char *id) {
 return createSymbol(symbolTable, id, VAR_KIND, 0);
}

user_defined_types: enum kind_t { CONST_KIND=0, FUNC_KIND=1, PARAM_KIND=2, PROC_KIND=3, TYPE_KIND=4, VAR_KIND=5 }

user_defined_types: union kind_union { struct ConstantKind *ConstKind; struct FunctionKind *FuncKind; struct ParamKind *ParamKind; struct ProcedureKind *ProcKind; struct TypeKind *TypeKind; struct VariableKind *VarKind; }

user_defined_types: struct ConstantKind { int constResultFlag; struct Symbol *typeSym; union anonymous_constant_value value; }

user_defined_types: struct ProcedureKind { struct ElementArray *params; char *label; }

user_defined_types: struct VariableKind { struct Symbol *typeSym; int byRef; }

user_defined_types: struct String { char *str; unsigned int strlen; }

user_defined_types: struct ElementArray { void **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct Procedure { struct ParamArray *params; char *label; }


createTypeSymbol

decompiled_code:
__int64 __fastcall createTypeSymbol(__int64 a1, unsigned int a2)
{
return createSymbol(symbolTable, a1, 4LL, a2);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, unsigned int a2)
{
return createSymbol(symbolTable, a1, 4LL, a2);
}

canonical_original_code:
struct Symbol *createTypeSymbol(char *id, int typeOriginator) {
 return createSymbol(symbolTable, id, TYPE_KIND, typeOriginator);
}

variable_types: typeOriginator int

user_defined_types: struct FunctionKind { struct Symbol *typeSym; struct ElementArray *params; char *label; int invocationInstance; }

user_defined_types: struct Array { struct Symbol *baseTypeSym; struct Symbol *indexTypeSym; }

user_defined_types: struct Function { struct ParamArray *params; struct Symbol *returnTypeSym; char *label; }

user_defined_types: struct Scalar { struct ElementArray *consts; }

user_defined_types: struct StringType { unsigned int strlen; }

user_defined_types: struct Subrange { int high; int low; struct Symbol *baseTypeSym; }

user_defined_types: struct ParamArray { struct Param **data; unsigned int len; unsigned int nElements; }

user_defined_types: struct hashElement { char *key; struct Symbol *symbol; struct hashElement *prev; struct hashElement *next; }