summaryrefslogtreecommitdiff
path: root/src/main/java/no/eliashaugsbakk/kompilator/semanticAnalysis/Analyzer.java
blob: 9452fc16931957e55da4f4c6025c263b5ee26f09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package no.eliashaugsbakk.kompilator.semanticAnalysis;

import static no.eliashaugsbakk.kompilator.tokenization.Keywords.KEYWORDS;

import no.eliashaugsbakk.kompilator.parsing.AST;
import no.eliashaugsbakk.kompilator.parsing.node.Program;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
import no.eliashaugsbakk.kompilator.parsing.node.expression.FunctionCall;
import no.eliashaugsbakk.kompilator.parsing.node.expression.StringLiteral;
import no.eliashaugsbakk.kompilator.parsing.node.statement.ExpressionStatement;
import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement;

public class Analyzer {
  private final AST ast;

  public Analyzer(AST ast) {
    this.ast = ast;
  }

  public void analyze() throws SemanticException {
    Program program = (Program) ast.getRoot();

    for (Statement stmt : program.statements) {
      analyzeStatement(stmt);
    }
  }

  private void analyzeStatement(Statement stmt) throws SemanticException {
    if (stmt instanceof ExpressionStatement exprStmt) {
      analyzeExpression(exprStmt.expression);
    } else {
      // Analyze the statement
      // NO other statements implemented
    }
  }

  private void analyzeExpression(Expression expr) throws SemanticException {
    if (expr instanceof FunctionCall call) {
      checkFunctionCall(call);
    } else {
      // analyze the expression
    }
  }

  private void checkFunctionCall(FunctionCall call) throws SemanticException {
    if (!KEYWORDS.contains(call.functionName)) {
      throw new SemanticException("unknown function: " + call.functionName);
    }

    if (call.arguments.size() != 1) {
      throw new SemanticException("print expects 1 argument, got " + call.arguments.size());
    }

    if (!(call.arguments.getFirst() instanceof StringLiteral)) {
      throw new SemanticException("print expects String argument only");
    }
  }
}