#pragma once

#include <unordered_map>
#include <vector>

#include "SysYParser.h"

class SemanticContext {
 public:
  void BindLValue(SysYParser::LValueContext* use,
                  antlr4::ParserRuleContext* def) {
    lvalue_defs_[use] = def;
  }

  void BindFuncCall(SysYParser::FuncCallExpContext* use,
                    SysYParser::FuncDefContext* def) {
    funccall_defs_[use] = def;
  }

  antlr4::ParserRuleContext* ResolveLValue(
      const SysYParser::LValueContext* use) const {
    auto it = lvalue_defs_.find(const_cast<SysYParser::LValueContext*>(use));
    return it == lvalue_defs_.end() ? nullptr : it->second;
  }

  SysYParser::FuncDefContext* ResolveFuncCall(
      const SysYParser::FuncCallExpContext* use) const {
    auto it = funccall_defs_.find(const_cast<SysYParser::FuncCallExpContext*>(use));
    return it == funccall_defs_.end() ? nullptr : it->second;
  }

 private:
  std::unordered_map<SysYParser::LValueContext*, antlr4::ParserRuleContext*>
      lvalue_defs_;
  std::unordered_map<SysYParser::FuncCallExpContext*,
                     SysYParser::FuncDefContext*>
      funccall_defs_;
};

SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);
