~emersion/arithm-parser

ba9a9034fdf7b17338e8f5c43b2bbd381377d620 — Simon Ser 7 months ago e64ed0c
Add pow
3 files changed, 35 insertions(+), 2 deletions(-)

M Makefile
M calc.c
M test.sh
M Makefile => Makefile +2 -1
@@ 1,10 1,11 @@
CC ?= cc
LDFLAGS = -lm
CFLAGS = -std=c11 -Wall -Wextra -Werror -Wno-unused-parameter

all: calc

%: %.c
	$(CC) $(CFLAGS) -o $@ $^
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^

.PHONY: clean
clean:

M calc.c => calc.c +30 -1
@@ 1,4 1,5 @@
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>


@@ 85,13 86,39 @@ struct ast_node *expect_ast_int(struct parser *parser) {
	return &i->node;
}

struct ast_node *expect_product(struct parser *parser) {
struct ast_node *expect_power(struct parser *parser) {
	struct ast_node *n = expect_ast_int(parser);
	if (n == NULL) {
		return NULL;
	}

	char chr = parser_peek_char(parser);
	if (chr == '^') {
		parser_read_char(parser);

		struct ast_node *right = expect_power(parser);
		if (right == NULL) {
			return NULL;
		}

		struct ast_binop *binop = calloc(1, sizeof(*binop));
		binop->node.type = AST_BINOP;
		binop->op = chr;
		binop->left = n;
		binop->right = right;
		return &binop->node;
	} else {
		return n;
	}
}

struct ast_node *expect_product(struct parser *parser) {
	struct ast_node *n = expect_power(parser);
	if (n == NULL) {
		return NULL;
	}

	char chr = parser_peek_char(parser);
	switch (chr) {
	case '*':
	case '/':


@@ 189,6 216,8 @@ int eval(struct ast_node *node) {
			return left * right;
		case '/':
			return left / right;
		case '^':
			return powl(left, right);
		default:
			assert(0);
		}

M test.sh => test.sh +3 -0
@@ 22,5 22,8 @@ expect "2*3" 6
expect "1+2*3" 7
expect "2*3+1" 7
expect "2*(3+1)" 8
expect "2^3" 8
expect "2^3^2" 512
expect "(2^3)^2" 64

exit $ret