Language: C++

#include<bits/stdc++.h>
using namespace std;

int h,w;
vector<string> field;
string s;
int p,cnt;
int y,x;
int dir;
int dy[]={-1,0,1,0};
int dx[]={0,1,0,-1};
vector<vector<vector<vector<int>>>> used;

void program();
void statement();
void _if();
void _while();
void act();
bool expr();

void skip(){
    int icnt=0;
    int wcnt=0;
    while(icnt>=0 && wcnt>=0){
        if(s[p]=='[') icnt++;
        if(s[p]==']') icnt--;
        if(s[p]=='{') wcnt++;
        if(s[p]=='}') wcnt--;
        p++;
    }
}

void flip(){
    dir=(dir+2)%4;
}
bool iswall(){
    return field[y+dy[dir]][x+dx[dir]]=='#';
}
bool end(){
    return p>=s.size() || s[p]==']' || s[p]=='}';
}

void program(){
    while(!end()){
        statement();
    }
    return;
}

void statement(){
    if(s[p]=='['){
        _if();
        return;
    }
    if(s[p]=='{'){
        _while();
        return;
    }
    act();
    return;
}

void _if(){
    assert(s[p]=='[');
    p++;
    if(!expr()){
        skip();
        return;
    }
    program();
    assert(s[p]==']');
    p++;
    return;
}

void _while(){
    while(true){
        if(used[y][x][p][dir]){
            throw "nonFin";
        }
        used[y][x][p][dir]=true;

        int prep=p;
        assert(s[p]=='{');
        p++;
        if(!expr()){
            skip();
            return;
        }
        program();
        assert(s[p]=='}');
        p=prep;
    }
}

void judge(){
    if(field[y][x]=='g') throw "Fin";
}

void act(){
    cnt++;
    char op=s[p];
    p++;
    switch(op){
        case '^':
            if(!iswall()){
                y=y+dy[dir];
                x=x+dx[dir];
            }
            judge();
            return;
        case 'v':
            flip();
            if(!iswall()){
                y=y+dy[dir];
                x=x+dx[dir];
            }
            flip();
            judge();
            return;
        case '<':
            dir=(dir+3)%4;
            return;
        case '>':
            dir=(dir+1)%4;
            return;
    }
    throw "Act Error";
}

bool expr(){
    bool hoge=(s[p]!='~');
    if(s[p]=='~') p++;
    char op=s[p];
    p++;
    switch(op){
        case 'N':
            return !((dir==0)^hoge);
        case 'E':
            return !((dir==1)^hoge);
        case 'S':
            return !((dir==2)^hoge);
        case 'W':
            return !((dir==3)^hoge);
        case 'C':
            return !(iswall()^hoge);
        case 'T':
            return hoge;
    }
    throw "Error Check";
}

void run(){
    cnt=0,p=0,dir=0;
    used.resize(h,vector<vector<vector<int>>>(w,vector<vector<int>>(s.size()+1,vector<int>(4,0))));
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(field[i][j]=='s'){
                y=i;
                x=j;
            }
        }
    }
    try{
        program();
    }catch(const char* ex){
        if(ex=="Fin"){
            return;
        }
        else if(ex=="nonFin"){
            cnt=-1;
            return;
        }
        else{
            cout<<ex<<endl;
            abort();
        }
    }
    return;
}

int main(){
    cin>>h>>w;
    field.resize(h);
    for(int i=0;i<h;i++) cin>>field[i];
    cin>>s;
    run();
    if(field[y][x]!='g') cnt=-1;
    cout<<cnt<<endl;
    return 0;
}

    return;
}

void _while(){
    while(true){
        if(used[y][x][p][dir]){
            throw "nonFin";
        }
        used[y][x][p][dir]=true;

        int prep=p;
        assert(s[p]=='{');
        p++;
        if(!expr()){
            skip();
            return;
        }
        program();
        assert(s[p]=='}');
        p=prep;
    }
}

void judge(){
    if(field[y][x]=='g') throw "Fin";
}

void act(){
    cnt++;
    char op=s[p];
    p++;
    switch(op){
        case '^':
            if(!iswall()){
                y=y+dy[dir];
                x=x+dx[dir];
            }
            judge();
            return;
        case 'v':
            flip();
            if(!iswall()){
                y=y+dy[dir];
                x=x+dx[dir];
            }
            flip();
            judge();
            return;
        case '<':
            dir=(dir+3)%4;
            return;
        case '>':
            dir=(dir+1)%4;
            return;
    }
    throw "Act Error";
}

bool expr(){
    bool hoge=(s[p]!='~');
    if(s[p]=='~') p++;
    char op=s[p];
    p++;
    switch(op){
        case 'N':
            return !((dir==0)^hoge);
        case 'E':
            return !((dir==1)^hoge);
        case 'S':
            return !((dir==2)^hoge);
        case 'W':
            return !((dir==3)^hoge);
        case 'C':
            return !(iswall()^hoge);
        case 'T':
            return hoge;
    }
    throw "Error Check";
}

void run(){
    cnt=0,p=0,dir=0;
    used.resize(h,vector<vector<vector<int>>>(w,vector<vector<int>>(s.size()+1,vector<int>(4,0))));
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(field[i][j]=='s'){
                y=i;
                x=j;
            }
        }
    }
    try{
        program();
    }catch(const char* ex){
        if(ex=="Fin"){
            return;
        }
        else if(ex=="nonFin"){
            cnt=-1;
            return;
        }
        else{
            cout<<ex<<endl;
            abort();
        }
    }
    return;
}

int main(){
    cin>>h>>w;
    field.resize(h);
    for(int i=0;i<h;i++) cin>>field[i];
    cin>>s;
    run();
    if(field[y][x]!='g') cnt=-1;
    cout<<cnt<<endl;
    return 0;
}

Compiler output:
a.cc:193:5: error: expected unqualified-id before 'return'
  193 |     return;
      |     ^~~~~~
a.cc:194:1: error: expected declaration before '}' token
  194 | }
      | ^
a.cc:196:6: error: redefinition of 'void _while()'
  196 | void _while(){
      |      ^~~~~~
a.cc:76:6: note: 'void _while()' previously defined here
   76 | void _while(){
      |      ^~~~~~
a.cc:216:6: error: redefinition of 'void judge()'
  216 | void judge(){
      |      ^~~~~
a.cc:96:6: note: 'void judge()' previously defined here
   96 | void judge(){
      |      ^~~~~
a.cc:220:6: error: redefinition of 'void act()'
  220 | void act(){
      |      ^~~
a.cc:100:6: note: 'void act()' previously defined here
  100 | void act(){
      |      ^~~
a.cc:251:6: error: redefinition of 'bool expr()'
  251 | bool expr(){
      |      ^~~~
a.cc:131:6: note: 'bool expr()' previously defined here
  131 | bool expr(){
      |      ^~~~
a.cc:273:6: error: redefinition of 'void run()'
  273 | void run(){
      |      ^~~
a.cc:153:6: note: 'void run()' previously defined here
  153 | void run(){
      |      ^~~
a.cc:302:5: error: redefinition of 'int main()'
  302 | int main(){
      |     ^~~~
a.cc:182:5: note: 'int main()' previously defined here
  182 | int main(){
      |     ^~~~