151 } |
153 } |
152 pool_free(pool, expr); |
154 pool_free(pool, expr); |
153 } |
155 } |
154 |
156 |
155 static NSAPIExpressionOperator expr_operator(cxstring token) { |
157 static NSAPIExpressionOperator expr_operator(cxstring token) { |
156 if(!cx_strcmp(token, cx_str("+"))) { |
158 if(!cx_strcmp(token, cx_str(","))) { |
|
159 return NSAPI_EXPRESSION_ARG; |
|
160 } else if(!cx_strcmp(token, cx_str("+"))) { |
157 return NSAPI_EXPRESSION_ADD; |
161 return NSAPI_EXPRESSION_ADD; |
158 } else if(!cx_strcmp(token, cx_str("-"))) { |
162 } else if(!cx_strcmp(token, cx_str("-"))) { |
159 return NSAPI_EXPRESSION_SUB; |
163 return NSAPI_EXPRESSION_SUB; |
160 } else if(!cx_strcmp(token, cx_str("*"))) { |
164 } else if(!cx_strcmp(token, cx_str("*"))) { |
161 return NSAPI_EXPRESSION_MUL; |
165 return NSAPI_EXPRESSION_MUL; |
261 // For example: 1 + - 2 |
265 // For example: 1 + - 2 |
262 // After + a value is expected, but there is the - operator |
266 // After + a value is expected, but there is the - operator |
263 // in that case, the - operator is a unary expression |
267 // in that case, the - operator is a unary expression |
264 if(op->expect_value) { |
268 if(op->expect_value) { |
265 // We expected a value but got an operator? This must be an unary operator |
269 // We expected a value but got an operator? This must be an unary operator |
|
270 |
|
271 if(op->operator == NSAPI_EXPRESSION_ARG && !parser->expect_arg) { |
|
272 // simplify unary arg |
|
273 pool_free(parser->pool, exp); |
|
274 parser->expect_value = TRUE; |
|
275 parser->expect_arg = FALSE; |
|
276 return 0; |
|
277 } |
|
278 |
266 exp->type = NSAPI_EXPRESSION_UNARY; |
279 exp->type = NSAPI_EXPRESSION_UNARY; |
267 exp->left = expr_parser_pop(parser); |
280 exp->left = expr_parser_pop(parser); |
268 exp->right = NULL; |
281 exp->right = NULL; |
269 } else { |
282 } else { |
270 // binary operator |
283 // binary operator |
271 exp->type = NSAPI_EXPRESSION_BINARY; |
284 exp->type = NSAPI_EXPRESSION_BINARY; |
272 exp->right = expr_parser_pop(parser); |
285 exp->right = expr_parser_pop(parser); |
273 exp->left = expr_parser_pop(parser); |
286 exp->left = expr_parser_pop(parser); |
278 } |
291 } |
279 |
292 |
280 cxListAdd(parser->ex_stack, exp); |
293 cxListAdd(parser->ex_stack, exp); |
281 |
294 |
282 parser->expect_value = TRUE; |
295 parser->expect_value = TRUE; |
|
296 parser->expect_arg = FALSE; |
|
297 return 0; |
|
298 } |
|
299 |
|
300 static int expr_add_func(ExprParser *parser, ExprOpStackItem *func) { |
|
301 NSAPIExpression *exp = pool_malloc(parser->pool, sizeof(NSAPIExpression)); |
|
302 if(!exp) { |
|
303 return 1; |
|
304 } |
|
305 exp->type = NSAPI_EXPRESSION_IDENTIFIER; |
|
306 exp->operator = NSAPI_EXPRESSION_CALL; |
|
307 exp->left = NULL; |
|
308 exp->right = NULL; |
|
309 exp->value.str = func->identifier; |
|
310 |
|
311 if(parser->ex_stack->size > 0) { |
|
312 NSAPIExpression *top = cxListAt(parser->ex_stack, parser->ex_stack->size - 1); |
|
313 if(top && top->operator == NSAPI_EXPRESSION_ARG) { |
|
314 exp->left = top; |
|
315 cxListRemove(parser->ex_stack, parser->ex_stack->size - 1); |
|
316 } |
|
317 } |
|
318 |
|
319 if(cxListAdd(parser->ex_stack, exp)) { |
|
320 return 1; |
|
321 } |
|
322 parser->expect_value = FALSE; |
283 return 0; |
323 return 0; |
284 } |
324 } |
285 |
325 |
286 // converts the token to a value expression (int, bool, str, ...) |
326 // converts the token to a value expression (int, bool, str, ...) |
287 // and adds it to parser->ex_stack |
327 // and adds it to parser->ex_stack |
290 NSAPIExpression *exp = pool_malloc(parser->pool, sizeof(NSAPIExpression)); |
330 NSAPIExpression *exp = pool_malloc(parser->pool, sizeof(NSAPIExpression)); |
291 ZERO(exp, sizeof(NSAPIExpression)); |
331 ZERO(exp, sizeof(NSAPIExpression)); |
292 if(expr_set_value(parser->pool, exp, token)) { |
332 if(expr_set_value(parser->pool, exp, token)) { |
293 return 1; |
333 return 1; |
294 } |
334 } |
|
335 |
295 cxListAdd(parser->ex_stack, exp); |
336 cxListAdd(parser->ex_stack, exp); |
|
337 if(parser->expect_arg) { |
|
338 ExprOpStackItem argList; |
|
339 argList.expect_value = TRUE; |
|
340 argList.identifier = (cxstring){NULL, 0}; |
|
341 argList.open_parenthesis = FALSE; |
|
342 argList.operator = NSAPI_EXPRESSION_ARG; |
|
343 if(expr_add_operator(parser, &argList)) { |
|
344 return 1; |
|
345 } |
|
346 } |
|
347 |
296 parser->expect_value = FALSE; |
348 parser->expect_value = FALSE; |
|
349 parser->expect_arg = FALSE; |
297 return 0; |
350 return 0; |
|
351 } |
|
352 |
|
353 static int token_is_identifier(cxstring token) { |
|
354 if(token.length == 0) { |
|
355 return 0; |
|
356 } |
|
357 |
|
358 if(!isalpha(token.ptr[0])) { |
|
359 return 0; |
|
360 } |
|
361 |
|
362 for(int i=1;i<token.length;i++) { |
|
363 if(!isalnum(token.ptr[i])) { |
|
364 return 0; |
|
365 } |
|
366 } |
|
367 |
|
368 if(!cx_strcmp(token, cx_str("true")) || !cx_strcmp(token, cx_str("false"))) { |
|
369 return 0; |
|
370 } |
|
371 |
|
372 return 1; |
298 } |
373 } |
299 |
374 |
300 |
375 |
301 static NSAPIExpression* expr_parse_expr(ExprParser *parser) { |
376 static NSAPIExpression* expr_parse_expr(ExprParser *parser) { |
302 CxList *op_stack = parser->op_stack; |
377 CxList *op_stack = parser->op_stack; |
307 for(;token.ptr;token=expr_next_token(parser->tokens, parser->pos)) { |
382 for(;token.ptr;token=expr_next_token(parser->tokens, parser->pos)) { |
308 NSAPIExpressionOperator op = expr_operator(token); |
383 NSAPIExpressionOperator op = expr_operator(token); |
309 if(op != NSAPI_EXPRESSION_NOOP) { |
384 if(op != NSAPI_EXPRESSION_NOOP) { |
310 ExprOpStackItem new_op; |
385 ExprOpStackItem new_op; |
311 new_op.operator = op; |
386 new_op.operator = op; |
|
387 new_op.identifier = (cxstring){NULL,0}; |
312 new_op.expect_value = parser->expect_value; |
388 new_op.expect_value = parser->expect_value; |
313 new_op.open_parenthesis = FALSE; |
389 new_op.open_parenthesis = FALSE; |
314 while(op_stack->size > 0) { |
390 while(op_stack->size > 0) { |
315 ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-1); |
391 ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-1); |
316 if(stack_item->operator == NSAPI_EXPRESSION_NOOP) { |
392 if(stack_item->operator == NSAPI_EXPRESSION_NOOP) { |
325 } |
401 } |
326 cxListRemove(op_stack, op_stack->size-1); |
402 cxListRemove(op_stack, op_stack->size-1); |
327 } |
403 } |
328 cxListAdd(op_stack, &new_op); |
404 cxListAdd(op_stack, &new_op); |
329 parser->expect_value = TRUE; |
405 parser->expect_value = TRUE; |
|
406 parser->expect_arg = FALSE; |
330 } else if(token.length == 1 && token.ptr[0] == '(') { |
407 } else if(token.length == 1 && token.ptr[0] == '(') { |
331 ExprOpStackItem new_op; |
408 ExprOpStackItem *prev_op = NULL; |
332 new_op.operator = NSAPI_EXPRESSION_NOOP; |
409 if(op_stack->size > 0) { |
333 new_op.expect_value = 0; |
410 prev_op = cxListAt(op_stack, op_stack->size - 1); |
334 new_op.open_parenthesis = 1; |
411 } |
335 cxListAdd(op_stack, &new_op); |
412 |
|
413 if(prev_op && prev_op->operator == NSAPI_EXPRESSION_CALL) { |
|
414 // function call open parenthesis |
|
415 // we don't need to add a new op stack item, just mark function |
|
416 // call as open parenthesis |
|
417 prev_op->open_parenthesis = TRUE; |
|
418 parser->expect_arg = TRUE; |
|
419 } else { |
|
420 ExprOpStackItem new_op; |
|
421 new_op.operator = NSAPI_EXPRESSION_NOOP; |
|
422 new_op.identifier = (cxstring){NULL,0}; |
|
423 new_op.expect_value = 0; |
|
424 new_op.open_parenthesis = TRUE; |
|
425 cxListAdd(op_stack, &new_op); |
|
426 } |
336 parser->expect_value = TRUE; |
427 parser->expect_value = TRUE; |
337 } else if(token.length == 1 && token.ptr[0] == ')') { |
428 } else if(token.length == 1 && token.ptr[0] == ')') { |
338 int found_open_bracket = FALSE; |
429 int found_open_bracket = FALSE; |
|
430 ExprOpStackItem stack_item; |
339 while(op_stack->size > 0) { |
431 while(op_stack->size > 0) { |
340 ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-1); |
432 ExprOpStackItem *stack_item_ptr = cxListAt(op_stack, op_stack->size-1); |
|
433 stack_item = *stack_item_ptr; |
341 cxListRemove(op_stack, op_stack->size-1); |
434 cxListRemove(op_stack, op_stack->size-1); |
342 if(stack_item->open_parenthesis) { |
435 if(stack_item.open_parenthesis) { |
343 found_open_bracket = TRUE; |
436 found_open_bracket = TRUE; |
344 break; |
437 break; |
345 } else { |
438 } else { |
346 if(expr_add_operator(parser, stack_item)) { |
439 if(expr_add_operator(parser, &stack_item)) { |
347 return NULL; |
440 return NULL; |
348 } |
441 } |
349 } |
442 } |
350 } |
443 } |
351 if(!found_open_bracket) { |
444 if(!found_open_bracket) { |
352 return NULL; |
445 return NULL; |
353 } |
446 } |
|
447 if(stack_item.operator == NSAPI_EXPRESSION_CALL) { |
|
448 if(expr_add_func(parser, &stack_item)) { |
|
449 return NULL; |
|
450 } |
|
451 } |
354 parser->expect_value = FALSE; |
452 parser->expect_value = FALSE; |
|
453 parser->expect_arg = FALSE; |
|
454 } else if(token_is_identifier(token)) { |
|
455 ExprOpStackItem new_op; |
|
456 new_op.operator = NSAPI_EXPRESSION_CALL; |
|
457 new_op.identifier = token; |
|
458 new_op.expect_value = 0; |
|
459 new_op.open_parenthesis = FALSE; |
|
460 cxListAdd(op_stack, &new_op); |
|
461 parser->expect_value = FALSE; |
|
462 parser->expect_arg = FALSE; |
355 } else { |
463 } else { |
356 if(expr_add_value(parser, token)) { |
464 if(expr_add_value(parser, token)) { |
357 return NULL; |
465 return NULL; |
358 } |
466 } |
359 } |
467 } |