Leaderboard
Popular Content
Showing content with the highest reputation on 01/13/2021 in all areas
-
EasyCodeIt - cross-platform AutoIt implementation
FrancescoDiMuro and 4 others reacted to TheDcoder for a topic
Hello everyone Happy belated new year, I am here to give you the monthly update on the progress, but unfortunately I don't have much to show besides 650+ new lines of code that I am working on, presenting C code is not easy, especially if it is still a work in progress. The work on the expression parse is going strong, I have already added support for the basic binary infix operations (+, -, *, / etc.) and some others, I am currently working on parsing comparison operations, logical conjunction (And & Or) is next. This new parsing algorithm is a lot more flexible and powerful compared to my last implementation, so this should allow me to implement all sorts of expressions that we will ever need Here is a snippet of the new code, related to expression parsing: struct Expression expression_get(struct Token *tokens, size_t count) { struct Expression expression = {.op = OP_NOP}; // Calculate the number of actual tokens (anything not a whitespace) size_t actual_count = 0; struct Token *actual_tokens = tokens; for (size_t i = 0; i < count; ++i) if (tokens[i].type != TOK_WHITESPACE) ++actual_count; if (actual_count == count) goto skip_strip; // Allocate a new array with only actual tokens actual_tokens = malloc(sizeof(struct Token) * actual_count); if (!actual_tokens) raise_mem("collecting actual tokens"); size_t actual_i = 0; for (size_t i = 0; i < count; ++i) if (tokens[i].type != TOK_WHITESPACE) actual_tokens[actual_i++] = tokens[i]; skip_strip:; enum Precedence precedence = PRE__START; bool success; do { success = expression_parse(actual_tokens, actual_count, precedence--, &expression); if (expression.op == OP_ERR) raise_error("Unable to parse expression", false); } while (!success); return expression; } bool expression_parse(struct Token *token, size_t count, enum Precedence precedence, struct Expression *expression) { static char *err_mem_ctx = "parsing expression"; size_t operand_count; if (count == 1) { expression->op = OP_NOP; struct Operand *term = malloc(sizeof(struct Operand)); if (!term) raise_mem(err_mem_ctx); term->type = OPE_PRIMITIVE; term->value = malloc(sizeof(struct Primitive)); if (!term->value) raise_mem(err_mem_ctx); *term->value = primitive_get(token); expression->operands = term; } else { bool success; switch (precedence) { case PRE_INV: if (token->type != TOK_OPERATOR || token->op_info.sym != OPR_SUB) return false; expression->op = OP_INV; expression->operands = expression_alloc_operands(operand_count = 1); *expression->operands[0].expression = expression_get(token + 1, count - 1); break; case PRE_NEG: if (token->type != TOK_WORD || token->keyword != KWD_NOT) return false; expression->op = OP_NOT; expression->operands = expression_alloc_operands(operand_count = 1); *expression->operands[0].expression = expression_get(token + 1, count - 1); break; case PRE_EXP: success = expression_parse_infix_binary(token, count, (enum Operator []){OPR_EXP}, 1, false, expression); if (!success) return false; operand_count = 2; break; case PRE_MUL_DIV: success = expression_parse_infix_binary(token, count, (enum Operator []){OPR_MUL, OPR_DIV}, 2, true, expression); if (!success) return false; operand_count = 2; break; case PRE_ADD_SUB: success = expression_parse_infix_binary(token, count, (enum Operator []){OPR_ADD, OPR_SUB}, 2, true, expression); if (!success) return false; operand_count = 2; break; case PRE_CAT: success = expression_parse_infix_binary(token, count, (enum Operator []){OPR_CAT}, 1, true, expression); if (!success) return false; operand_count = 2; break; case PRE_COMP: success = expression_parse_comp(token, count); if (!success) return false; operand_count = 2; break; default: expression->op = OP_ERR; return false; } // Flatten expression operands for (size_t i = 0; i < operand_count; ++i) { if (expression->operands[i].expression->op == OP_NOP) { struct Expression *wrapped_expression = expression->operands[i].expression; expression->operands[i] = wrapped_expression->operands[0]; free(wrapped_expression); } } } return true; } bool expression_parse_infix_binary(struct Token *tokens, size_t count, enum Operator opr_list[], size_t opr_count, bool left, struct Expression *expression) { if (count < 3) return false; struct Token *op_token = find_token_by_opr(tokens, count, opr_list, opr_count, left); if (!op_token) return false; expression->op = opr_to_op(op_token->op_info.sym); expression->operands = expression_alloc_operands(2); *expression->operands[0].expression = expression_get(tokens, op_token - tokens); *expression->operands[1].expression = expression_get(op_token + 1, count - (op_token - tokens) - 1); return true; } bool expression_parse_comp(struct Token *tokens, size_t count) { if (count < 3) return false; struct Token *op_token = find_token_by_opr(tokens, count, (enum Operator []){OPR_GRT, OPR_LES, OPR_EQU}, 3, true); if (!op_token) return false; if (op_token == tokens || op_token == &tokens[count - 1]) return false; } struct Operand *expression_alloc_operands(size_t count) { static char *err_mem_ctx = "adding operands to an operation"; // Allocate space for operand array struct Operand *operands = malloc(sizeof(struct Operand) * count); if (!operands) raise_mem(err_mem_ctx); // Initialize each element with an empty expression for (size_t i = 0; i < count; ++i) { operands[i].type = OPE_EXPRESSION; operands[i].expression = malloc(sizeof(struct Expression)); if (!operands[i].expression) raise_mem(err_mem_ctx); } return operands; } struct Token *find_token_by_opr(struct Token *tokens, size_t count, enum Operator opr_list[], size_t opr_count, bool left) { size_t open_brackets = 0; size_t i = left ? 0 : count - 1; while (true) { if (tokens[i].type == TOK_BRACKET && tokens[i].data[0] == '(') { ++open_brackets; goto next; } if (open_brackets) { if (tokens[i].type == TOK_BRACKET && tokens[i].data[0] == ')') --open_brackets; goto next; } if (tokens[i].type == TOK_OPERATOR) { for (size_t opr = 0; opr < opr_count; ++opr) if (tokens[i].op_info.sym == opr_list[opr]) return tokens + i; } // Iterate next: if (left) {if (i == count) break; ++i;} else {if (i == 0) break; --i;} } return NULL; } I wish I had something more pretty to show you, but that's all I've got for the moment and I am working to complete this. Once expression parsing is done I can focus on parsing statements and then eventually implement a backend to actually execute the code, the proof of concept would be complete by that time -- I have been pretty busy with all sorts of stuff, so I haven't been able to dedicate as much time as I wished to work on this, so the progress is somewhat slow. However I have been changing my routine to allow me to work on a faster pace, so hopefully the next update will come sooner than a month! That's it for now folks, peace! ✌️5 points -
1 point
-
Silent Installation (To software there is no silent switch)
PHAK reacted to abberration for a topic
I just tried WinSetState("Install", "", @SW_HIDE) on the installer and it hid the window. Are you saying that hiding the window interferes with the installation?1 point -
Silent Installation (To software there is no silent switch)
Earthshine reacted to PHAK for a topic
@Earthshine Thanks I succeeded #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Add_Constants=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include 'WaitForControls.au3' #include 'log4a.au3' #Region ;**** Logging **** ; Enable logging and don't write to stderr _log4a_SetEnable() ; Write to stderr, set min level to warn, customize message format _log4a_SetErrorStream() _log4a_SetMinLevel($LOG4A_LEVEL_INFO) ; If @compiled Then _log4a_SetMinLevel($LOG4A_LEVEL_WARN) ; Change the min level if the script is compiled _log4a_SetFormat("${date} | ${host} | ${level} | ${message}") #EndRegion ;**** Logging **** Run('C:\Users\PC\Desktop\A.exe') $handle = WinGetHandle('A.exe') _checkClickCtrl('[CLASS:#32770]', 'Install', '[CLASS:Button; INSTANCE:4]', '&Next >') _checkClickCtrl('[CLASS:#32770]', 'Installation Options', '[CLASS:Button; INSTANCE:11]', 'Finish') _checkClickCtrl('[CLASS:#32770]', 'Installation Complete', '[CLASS:Button; INSTANCE:1]', 'OK') I did well? What am I doing that will run in the background and not be seen I tried WinSetState("Install", "", @SW_HIDE) Not good can you help? Thank you1 point -
how create a table with koda
axxbryan reacted to FrancescoDiMuro for a topic
@axxbryan The ListView is in the Win32 tab. If you hover with the mouse on the control, you have a tooltip showing its type1 point -
EasyCodeIt - cross-platform AutoIt implementation
TheSaint reacted to JockoDundee for a topic
Don’t think about it so much1 point -
Silent Installation (To software there is no silent switch)
PHAK reacted to Earthshine for a topic
I have a handy little controlclick wrapper function i posted on this forum for use in creating automated installers. I need to test all our product installers both silent and GUI so I use that.. It's called WaitForControls.au3 and it requires the use of log4a.au3 (logger) I prefer ControlClick. I try to use ControlSend if ControlClick doesn't work It makes it real easy to write a clean installer AutoIt script.1 point