blob: 2b431769aa373fc68dd7ee761fc6a03b5a7fab56 [file] [log] [blame]
Shinichiro Hamajib69bf8a2015-06-10 14:52:06 +09001// Copyright 2015 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090015package kati
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090016
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +090017import (
18 "strings"
19
20 "github.com/golang/glog"
21)
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090022
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +090023type ast interface {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090024 eval(*Evaluator) error
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090025 show()
26}
27
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +090028type assignAST struct {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090029 srcpos
Shinichiro Hamaji7825b652015-06-04 13:47:14 +090030 lhs Value
31 rhs Value
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090032 op string
Fumitoshi Ukaib2c300f2015-04-23 00:59:26 +090033 opt string // "override", "export"
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090034}
35
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090036func (ast *assignAST) eval(ev *Evaluator) error {
37 return ev.evalAssign(ast)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090038}
39
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090040func (ast *assignAST) evalRHS(ev *Evaluator, lhs string) (Var, error) {
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090041 origin := "file"
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090042 if ast.filename == bootstrapMakefileName {
Fumitoshi Ukai103a7962015-04-08 15:53:53 +090043 origin = "default"
44 }
Fumitoshi Ukaib2c300f2015-04-23 00:59:26 +090045 if ast.opt == "override" {
46 origin = "override"
47 }
48 // TODO(ukai): handle ast.opt == "export"
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090049 switch ast.op {
50 case ":=":
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +090051 switch v := ast.rhs.(type) {
52 case literal:
Fumitoshi Ukai7655f182015-07-15 14:05:41 +090053 return &simpleVar{value: []string{v.String()}, origin: origin}, nil
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +090054 case tmpval:
Fumitoshi Ukai7655f182015-07-15 14:05:41 +090055 return &simpleVar{value: []string{v.String()}, origin: origin}, nil
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +090056 default:
Fumitoshi Ukaia4a02252015-07-09 14:25:18 +090057 var buf evalBuffer
58 buf.resetSep()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090059 err := v.Eval(&buf, ev)
60 if err != nil {
61 return nil, err
62 }
Fumitoshi Ukai7655f182015-07-15 14:05:41 +090063 return &simpleVar{value: []string{buf.String()}, origin: origin}, nil
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +090064 }
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090065 case "=":
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090066 return &recursiveVar{expr: ast.rhs, origin: origin}, nil
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090067 case "+=":
Fumitoshi Ukaia483ec02015-06-26 10:12:02 +090068 prev := ev.lookupVarInCurrentScope(lhs)
Fumitoshi Ukaic1847602015-04-02 16:18:02 +090069 if !prev.IsDefined() {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090070 return &recursiveVar{expr: ast.rhs, origin: origin}, nil
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090071 }
Shinichiro Hamaji7825b652015-06-04 13:47:14 +090072 return prev.AppendVar(ev, ast.rhs)
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090073 case "?=":
Fumitoshi Ukaia483ec02015-06-26 10:12:02 +090074 prev := ev.lookupVarInCurrentScope(lhs)
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090075 if prev.IsDefined() {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090076 return prev, nil
Shinichiro Hamaji69b7f652015-03-31 01:01:59 +090077 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090078 return &recursiveVar{expr: ast.rhs, origin: origin}, nil
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090079 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090080 return nil, ast.errorf("unknown assign op: %q", ast.op)
Fumitoshi Ukaie1b813c2015-03-30 18:38:21 +090081}
82
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +090083func (ast *assignAST) show() {
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +090084 glog.Infof("%s %s %s %q", ast.opt, ast.lhs, ast.op, ast.rhs)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090085}
86
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +090087// maybeRuleAST is an ast for rule line.
Shinichiro Hamajide829712015-03-31 18:26:56 +090088// Note we cannot be sure what this is, until all variables in |expr|
89// are expanded.
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +090090type maybeRuleAST struct {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090091 srcpos
Fumitoshi Ukai201df422015-07-07 17:31:05 +090092 isRule bool // found literal ':'
93 expr Value
94 assign *assignAST // target specific var
95 semi []byte // after ';' if ';' exists
Fumitoshi Ukai119dc912015-03-30 16:52:41 +090096}
97
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090098func (ast *maybeRuleAST) eval(ev *Evaluator) error {
99 return ev.evalMaybeRule(ast)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900100}
101
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900102func (ast *maybeRuleAST) show() {
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900103 glog.Info(ast.expr)
Fumitoshi Ukai119dc912015-03-30 16:52:41 +0900104}
Shinichiro Hamaji685fecf2015-03-30 18:28:12 +0900105
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900106type commandAST struct {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900107 srcpos
Fumitoshi Ukai103a7962015-04-08 15:53:53 +0900108 cmd string
Shinichiro Hamaji0b93c862015-04-07 06:15:15 +0900109}
110
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900111func (ast *commandAST) eval(ev *Evaluator) error {
112 return ev.evalCommand(ast)
Shinichiro Hamaji0b93c862015-04-07 06:15:15 +0900113}
114
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900115func (ast *commandAST) show() {
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900116 glog.Infof("\t%s", strings.Replace(ast.cmd, "\n", `\n`, -1))
Shinichiro Hamaji0b93c862015-04-07 06:15:15 +0900117}
118
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900119type includeAST struct {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900120 srcpos
Shinichiro Hamajid7bef602015-03-30 19:55:32 +0900121 expr string
122 op string
123}
124
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900125func (ast *includeAST) eval(ev *Evaluator) error {
126 return ev.evalInclude(ast)
Shinichiro Hamajid7bef602015-03-30 19:55:32 +0900127}
128
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900129func (ast *includeAST) show() {
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900130 glog.Infof("include %s", ast.expr)
Shinichiro Hamajid7bef602015-03-30 19:55:32 +0900131}
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900132
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900133type ifAST struct {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900134 srcpos
Shinichiro Hamajiae32b782015-03-31 14:41:19 +0900135 op string
Shinichiro Hamaji1a68fd22015-06-04 14:46:56 +0900136 lhs Value
137 rhs Value // Empty if |op| is ifdef or ifndef.
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900138 trueStmts []ast
139 falseStmts []ast
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900140}
141
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900142func (ast *ifAST) eval(ev *Evaluator) error {
143 return ev.evalIf(ast)
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900144}
145
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900146func (ast *ifAST) show() {
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900147 // TODO
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900148 glog.Info("if")
Shinichiro Hamaji497754d2015-03-31 02:02:11 +0900149}
Shinichiro Hamaji7e521422015-05-29 14:23:30 +0900150
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900151type exportAST struct {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900152 srcpos
Fumitoshi Ukaif5b916d2015-07-15 15:57:19 +0900153 expr []byte
154 hasEqual bool
155 export bool
Shinichiro Hamaji7e521422015-05-29 14:23:30 +0900156}
157
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900158func (ast *exportAST) eval(ev *Evaluator) error {
159 return ev.evalExport(ast)
Shinichiro Hamaji7e521422015-05-29 14:23:30 +0900160}
161
Fumitoshi Ukai91ed5d72015-06-25 13:08:09 +0900162func (ast *exportAST) show() {
Shinichiro Hamaji7e521422015-05-29 14:23:30 +0900163 // TODO
Fumitoshi Ukai6450d0f2015-07-10 16:34:06 +0900164 glog.Info("export")
Shinichiro Hamaji7e521422015-05-29 14:23:30 +0900165}
Fumitoshi Ukai09fcd522015-07-15 14:31:50 +0900166
167type vpathAST struct {
168 srcpos
169 expr Value
170}
171
172func (ast *vpathAST) eval(ev *Evaluator) error {
173 return ev.evalVpath(ast)
174}
175
176func (ast *vpathAST) show() {
177 glog.Infof("vpath %s", ast.expr.String())
178}