mirror of https://gitlab.com/basile.b/dexed.git
#104, handle iasm
This commit is contained in:
parent
76df25458c
commit
7e5de81f80
|
@ -1,9 +1,9 @@
|
||||||
module halstead;
|
module halstead;
|
||||||
|
|
||||||
import
|
import
|
||||||
std.algorithm.iteration, std.conv, std.json, std.meta;
|
std.algorithm, std.conv, std.json, std.meta;
|
||||||
import
|
import
|
||||||
std.stdio, std.range: iota;
|
std.stdio, std.ascii, std.digest.crc, std.range: iota;
|
||||||
import
|
import
|
||||||
dparse.ast, dparse.lexer, dparse.parser, dparse.rollback_allocator;
|
dparse.ast, dparse.lexer, dparse.parser, dparse.rollback_allocator;
|
||||||
import
|
import
|
||||||
|
@ -82,6 +82,16 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addOperandFromToken(const ref Token tk)
|
||||||
|
{
|
||||||
|
if (isLiteral(tk.type))
|
||||||
|
{
|
||||||
|
alias immutHexStr = toHexString!(Order.increasing, LetterCase.upper);
|
||||||
|
++operands["literal" ~ immutHexStr(tk.text.crc32Of)];
|
||||||
|
}
|
||||||
|
else ++operands[tk.text];
|
||||||
|
}
|
||||||
|
|
||||||
void pushExprFlags(bool leftFlag = false, bool rightFlag = false)
|
void pushExprFlags(bool leftFlag = false, bool rightFlag = false)
|
||||||
{
|
{
|
||||||
binExprFlag.length += 1;
|
binExprFlag.length += 1;
|
||||||
|
@ -107,7 +117,6 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
|
|
||||||
void serialize()
|
void serialize()
|
||||||
{
|
{
|
||||||
import std.stdio: write;
|
|
||||||
JSONValue js;
|
JSONValue js;
|
||||||
js["functions"] = fs;
|
js["functions"] = fs;
|
||||||
js.toString.write;
|
js.toString.write;
|
||||||
|
@ -151,7 +160,6 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
|
|
||||||
version(unittest)
|
version(unittest)
|
||||||
{
|
{
|
||||||
import std.stdio: writeln;
|
|
||||||
writeln(functions[$-1]);
|
writeln(functions[$-1]);
|
||||||
writeln("\toperators: ",operators);
|
writeln("\toperators: ",operators);
|
||||||
writeln("\toperands : ",operands);
|
writeln("\toperands : ",operands);
|
||||||
|
@ -164,15 +172,7 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
{
|
{
|
||||||
ta.accept(this);
|
ta.accept(this);
|
||||||
if (ta.templateSingleArgument)
|
if (ta.templateSingleArgument)
|
||||||
{
|
addOperandFromToken(ta.templateSingleArgument.token);
|
||||||
if (!isLiteral(ta.templateSingleArgument.token.type))
|
|
||||||
++operands[ta.templateSingleArgument.token.text];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
import std.digest.crc: crc32Of, toHexString;
|
|
||||||
++operands["literal" ~ ta.templateSingleArgument.token.text.crc32Of.toHexString.idup];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const(FunctionCallExpression) expr)
|
override void visit(const(FunctionCallExpression) expr)
|
||||||
|
@ -184,7 +184,7 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
if (expr.templateArguments)
|
if (expr.templateArguments)
|
||||||
{
|
{
|
||||||
if (expr.templateArguments.templateSingleArgument)
|
if (expr.templateArguments.templateSingleArgument)
|
||||||
++operands[expr.templateArguments.templateSingleArgument.token.text];
|
addOperandFromToken(expr.templateArguments.templateSingleArgument.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr.accept(this);
|
expr.accept(this);
|
||||||
|
@ -256,11 +256,7 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
++operands[primary.identifierOrTemplateInstance.identifier.text];
|
++operands[primary.identifierOrTemplateInstance.identifier.text];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (primary.primary.type.isLiteral)
|
else addOperandFromToken(primary.primary);
|
||||||
{
|
|
||||||
import std.digest.crc: crc32Of, toHexString;
|
|
||||||
++operands["literal" ~ primary.primary.text.crc32Of.toHexString.idup];
|
|
||||||
}
|
|
||||||
primary.accept(this);
|
primary.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +292,39 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
if (expr.suffix.type)
|
if (expr.suffix.type)
|
||||||
++operators[str(expr.suffix.type)];
|
++operators[str(expr.suffix.type)];
|
||||||
}
|
}
|
||||||
|
override void visit(const(AsmInstruction) ai)
|
||||||
|
{
|
||||||
|
if (ai.identifierOrIntegerOrOpcode != tok!"")
|
||||||
|
{
|
||||||
|
++operators[ai.identifierOrIntegerOrOpcode.text];
|
||||||
|
}
|
||||||
|
ai.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const(Register) reg)
|
||||||
|
{
|
||||||
|
if (reg.identifier != tok!"")
|
||||||
|
{
|
||||||
|
++operands[reg.identifier.text];
|
||||||
|
}
|
||||||
|
if (reg.hasIntegerLiteral)
|
||||||
|
{
|
||||||
|
addOperandFromToken(reg.intLiteral);
|
||||||
|
}
|
||||||
|
reg.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void visit(const(AsmPrimaryExp) ape)
|
||||||
|
{
|
||||||
|
if (ape.token != tok!"")
|
||||||
|
addOperandFromToken(ape.token);
|
||||||
|
if (ape.identifierChain)
|
||||||
|
ape.identifierChain.identifiers
|
||||||
|
.filter!(a => !a.text.among("dword","ptr"))
|
||||||
|
.each!(a => addOperandFromToken(a));
|
||||||
|
|
||||||
|
ape.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
override void visit(const(IndexExpression) expr)
|
override void visit(const(IndexExpression) expr)
|
||||||
{
|
{
|
||||||
|
@ -358,11 +387,6 @@ private final class HalsteadMetric: ASTVisitor
|
||||||
++operators["else"];
|
++operators["else"];
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const(DeclarationOrStatement) st)
|
|
||||||
{
|
|
||||||
st.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
override void visit(const(WhileStatement) st)
|
override void visit(const(WhileStatement) st)
|
||||||
{
|
{
|
||||||
++operators["while"];
|
++operators["while"];
|
||||||
|
@ -1211,7 +1235,6 @@ unittest
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
//TODO: handle iasm
|
|
||||||
Function r =
|
Function r =
|
||||||
q{
|
q{
|
||||||
void foo()
|
void foo()
|
||||||
|
@ -1219,7 +1242,60 @@ unittest
|
||||||
asm{xor EAX,ECX;}
|
asm{xor EAX,ECX;}
|
||||||
}
|
}
|
||||||
}.test;
|
}.test;
|
||||||
//assert(r.operandsKinds == 2);
|
assert(r.operandsKinds == 2);
|
||||||
//assert(r.operatorsKinds == 1);
|
assert(r.operatorsKinds == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
// needs https://github.com/Hackerpilot/libdparse/pull/124
|
||||||
|
Function r =
|
||||||
|
q{
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
asm{mov EAX, SS:CL;}
|
||||||
|
}
|
||||||
|
}.test;
|
||||||
|
//assert(r.operandsKinds == 3);
|
||||||
|
assert(r.operatorsKinds == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Function r =
|
||||||
|
q{
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
asm{mov EAX, a.b.c;}
|
||||||
|
}
|
||||||
|
}.test;
|
||||||
|
assert(r.operandsKinds == 4);
|
||||||
|
assert(r.operatorsKinds == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Function r =
|
||||||
|
q{
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
asm{imul EAX, dword [EBP + EBX * 4 + 0x0FFFFFFD4];}
|
||||||
|
}
|
||||||
|
}.test;
|
||||||
|
assert(r.operandsKinds == 5);
|
||||||
|
assert(r.operatorsKinds == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
Function r =
|
||||||
|
q{
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
asm{imul EAX, ECX, dword[ESP + 8];}
|
||||||
|
}
|
||||||
|
}.test;
|
||||||
|
assert(r.operandsKinds == 4);
|
||||||
|
assert(r.operatorsKinds == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue