📄 vtc.doc
字号:
Usually, that code would be written: if (a) b; else if (c) d; else if (e) f; else g;This more elegantly conveys the effect of the code, which is toevaluate the conditions (<a>, <c> and <e>) until one is true, andexecute either <b>, <d>, <f> or <g> accordingly.The while statement is a loop statement, and has the following format: while (expression) statementThis causes the statement to be executed as long as the expression istrue. If the expression is false the first time it is evaluated, thestatement is never executed. The do-while loop: do statement while (expression)also executes a statement as long as an expression is true, but thestatement is always executed at least once, before the expression isever evaluated.Different types of flow control statements can be combined: while (input_waiting(rmt)) { if (line = read(rmt)) add_hist(obj(rmt)[1], line); else abort(); }The for statement is a loop statement with the format: for (expr1; expr2; expr3) statementexpr1 is evaluated immediately and its value is discarded. Theinterpreter then executes the statement as long as expr2 is true.expr3 is evaluated after each iteration of statement. For-loops canbe rewritten as while loops (this is not a perfect isomorphism, sincebreak and continue statements will not behave quite the same): expr1; while (expr2) { statement; expr3; }The logic behind the organization of the for statement is: expr1 isthe initialization expression. If you are writing a for statement tocount from 1 to 10, using the variable "i" as a counter, then expr1would be "i = 1". expr2 is the condition; for our example, we woulduse, "i <= 10". expr3 is the increment expression. In this case, itwould be "i++". The statement is the body of the loop; if we wantedto output the value of i on a line each time it counted, we would use"echo(itoa(i), "\n");" for our statement. So, we have: for (i = 1; i <= 10; i++) echo(itoa(i), "\n");For statements are convenient for separating the information about howlong the loop will run from the action that is taken at each stage ofthe loop.A label can be attached to any statement: label : statementThe label is an identifier. You can jump to a statement using a gotostatement: goto label;Goto statements can confuse the meaning of code and should be avoidedas much as possible. A goto label must be in the same function orcommand as the goto statement that jumps to it.The break and continue statements can be used within the statementpart of while, do-while and for loops. They have the forms break;and continue;The break statement terminates the loop. The continue statement jumpsto the end of the statement part of the loop and continues executionof the loop. In a for-loop, this means evaluating the iterationexpression before checking the condition expression.The return statement can be either: return;or return expression;This instructs the interpreter to exit the current function, returningthe value of expression if one is given. If the return statement isused inside a command (rather than a function), it will terminate thecommand.Functions---------Functions are blocks of code that are associated with a name, and canbe used run by calling them by name. The form of a functiondefinition is: func name(parameters) [local vars] compound statementThe word "func" is literal. The parameter names are a list ofidentifiers separated by commas, as are the local variable names.If a function does nothing but return an expression, there is a shortform: func name(parameters) --> exprParameter variables refer to the arguments to the function. It is arun-time error to call a function with fewer arguments than there areparameter variables in the function's definition. All arguments arepassed by value, so a function can reassign to its parameter variableswithout affecting the values of any variables whose values were passedto the function as arguments. As an example, the following: func switch(a, b) [temp] { temp = a; a = b; b = temp; }will perform no useful task, since switch() knows only the values ofthe arguments.It is okay to call a function with more arguments than it hasparameter variables. A function can use the argc and argv builtins(see vt.doc) to access its arguments directly.Local variables are variables whose scope (the area one can use themin) is restricted to the function. They are also distinct from anyother variable in the program in each invocation of the function. Alocal variable "i" in one function will not conflict with a localvariable "i" in some other function, and the local variables of afunction that calls itself, or of two functions that call each other,will not conflict with each other. This is important for creatingrecursive functions, which can call themselves repeatedly.Pointers and lvalues--------------------VTC has several types of pointers. These can be categorized into twoclasses. Pointers to primitives, remote connections, windows, keybindings, files, functions, regexps, association types, and propertylists are used by the interpreter to refer to objects, and can only bemanipulated by use of primitives (except for the -> operator in thecase of association types and property lists, q.v.). For instance,the primitive split() returns a pointer to the window that it creates,and other primitives such as win_top() and close() will accept thispointer as an argument.Strings and arrays are used for storing data. A string pointer pointsto a character value within a string, and an array pointer points to adata element within an array. Both can both be dereferenced by the *unary operator to yield the value that they point to.A string constant such as "foobar" is an expression with a stringpointer type. If we set: stringvar = "foobar";Then stringvar's value will be a string pointer, which can bevisualized like so: ------------------------- | f | o | o | b | a | r | ------------------------- ^---stringvarNow *stringvar has the value 'f'.You can access further elements of foobar using pointer arithmetic. In the above example, (stringvar + 4) is a string pointer pointing to the 'b' in "foobar". If we set: stringvar += 4;Then we can visualize foobar as: ------------------------- | f | o | o | b | a | r | ------------------------- ^---stringvarAnd *stringvar has the value 'b'. One can access string elementsbehind stringvar by subtracting from it; *(stringvar - 2) has thevalue 'o', since (stringvar - 2) points to the first 'o' in "foobar".A third operation on pointers is pointer subtraction. Suppose we set: stringvar2 = stringvar - 2;Now stringvar points to the 'b' and stringvar2 points to the 'o' twospaces behind it. We can find the distance between stringvar andstringvar2 by subtracting them: (stringvar2 - stringvar) has the value2. The - operator can only be used on string pointers that point tothe same string.Pointer arithmetic has the following operations: pointer + integer --> pointer pointer - integer --> pointer pointer - pointer --> integerThese operations apply to string pointers and array pointers. Anarray pointer acts just like a string pointer, except that arrayelements are not restricted to being characters.Relational and equality operators (<, <=, >=, >, ==, !=) also apply topointers that point inside the same string or array. It is a run-timeerror to use <, <=, >=, or > on pointers that point inside differentstrings or arrays. The == and != operators will always return falseif their arguments are pointers from different strings or arrays, orare of different types.The [] brackets are used to do array references. The expression: a[b]is equivalent to: *((a) + (b))That is, in the example above, stringvar[2] would have the value 'r',since it is the same as *(stringvar + 2).An lvalue is defined as an object that one can meaningfully find theaddress of. The two types of lvalues are variable names anddereferenced pointers. Since 'stringvar' is a variable name, it waslegal to use it on the left-hand side of the '=' operator. One couldalso write: *stringvar = 'm'which changes the 'b' in "foobar" to 'm'.The & operator can be used to get the address of an lvalue. This isusually an array pointer, since variables are treated as elements inan array. We could set: ptrtostringvar = &stringvar;Now we could do: *ptrtostringvar = "snafu";And stringvar would now point to the 's' in "snafu". & can alsoreturn a string pointer; for instance, &(*(stringvar + 2))would be a string pointer pointing to the 'a' in "snafu". This ismore commonly written: &stringvar[2]It could, of course, also be written as (stringvar + 2).We can write a swap() function using pointers: func swap(a, b) [t] { t = *a; *a = *b; *b = t; }Now if we wanted to switch the values of stringvar and stringvar2, wewould write: swap(&stringvar1, &stringvar2);Strings-------Strings are blocks of data containing character values. A charactervalue is an integer data value restricted (usually) to 256 values, ofwhich 0-127 are the most commonly used. Character constants are inthis range, and are the most common thing stored in a string.A string is null-terminated; that is, it has meaningful data valuesonly up to its first 0 value. So if we write: stringvar = "foobar"; stringvar[2] = 0;Then stringvar now points to "fo", and the rest of the contents of thestring are irrecoverable.The length of a string pointed to by a string pointer is defined asthe number of characters between the pointer and a 0 value, and isreturned by the strlen() primitive. After the above code has beenexecuted, strlen(stringvar) is 2, and strlen(stringvar + 1) is 1.Reading before the beginning or beyond the end of a string yields a 0value. This means stringvar[3] and stringvar[-1] have the value 0,and both strlen(&stringvar[3]) and strlen(&stringvar[-1]) are 0.Attempting to write (assign) before the beginning of a string is arun-time error. Writing beyond the end of a string is legal, andcauses the string to be lengthened, using spaces to fill in theintervening values. The statement: stringvar[10] = 'a';causes stringvar to point to "fo a".The + operator can be used to concatenate springs. Two stringpointers can be added together to return another string. Forinstance, one could write: a = "foo"; b = "bar"; c = a + b;and c would point to a string "foobar";.It is important to distinguish between separate copies of astring. The strdup() primitive returns a copy of a string. If wewrite: a = "foo"; b = a + 1; *b = 'b'; a++;then *a is 'b'. We could also write: a = "foo"; b = strdup(a + 1); *b = 'b'; a++;and *a is still 'o', since it was a copy of a that was modified, notthe original.The += operator can be used with strings. If we write: stringvar += stringexpr;then stringexpr is concatenated onto the contents of stringvar. Thisis equivalent to: stringvar = stringvar + (stringexpr);Note that this is not quite the same as strcat(stringvar, stringexpr);because the += operator produces a new string, while strcat() acts onthe old string. If we write: a = "foo"; b = a + 4; strcat(a, "bar");then b points to the "ar" at the end of "foobar". If we write: a = "foo"; b = a + 4; a += "bar";then *b is 0, since it's beyond the end of "foo". a no longer pointswithin the same string as b.Property lists--------------Property lists vaguely mirror structures in C. The idea is, youdefine an association type, use it to create a property list, and thenyou can refer to elements in the property list by name. For instance,suppose we wanted to create a data type called "pair", with a "car"and a "cdr" element. We would write: Tpair = new_assoc(); // ... some_pair = alloc(2, Tpair); some_pair->car = ...; some_pair->cdr = ...;The alloc(number, assoc) call creates a property list. A plist iscomposed of an array and an association type. The association type isnot terribly important; it contains the size of the array ('car' inthis plist might point to element 0 in the array, whereas 'name' mightalso point to element 0 in another plist of another association type)and defines the order of elements in the array, which is useful whenwe want to get at the array directly using the base() primitive. Seevt.doc for details.Other data types----------------The other data types are generally related to specific clientfeatures, and are described in vt.doc. See the sections in that file.vt.doc also contains documentation on primitives.Operators---------This is a list of the ways binary operators can be used in VTC,excluding the assignment operators. "ptr" refers to an array pointeror string pointer. With the exception of the + operator, operationsinvolving two pointer types require that the pointers by of the sametype, and that they point inside the same array or string. The +operator can take two string pointers that point inside differentstrings, but cannot operate on two array pointers. "int" refers to aninteger, and "bool" refers to a boolean value. As a result, a booleanvalue is either 0 or 1; as an argument, it can be any data type.int * int --> int (integer multiplication)int / int --> int (integer division)int % int --> int (integer modulus)int + int --> int (integer addition)ptr + int --> ptr (pointer addition)ptr + ptr --> ptr (string concatenation)int - int --> int (integer subtraction)ptr - int --> ptr (pointer subtraction)ptr - ptr --> int (distance between pointers)int << int --> int (bitwise left shift)int >> int --> int (bitwise right shift)int < int --> bool (integer comparison)ptr < ptr --> bool (pointer comparison)(<=, >=, >, ==, and != act in the same way as <)int & int --> int (bitwise and)int ^ int --> int (bitwise xor)int | int --> int (bitwise or)bool && bool --> bool (logical and)bool ^^ bool --> bool (logical xor)bool || bool --> bool (logical or)The == and != operators can also be used to test for equality ofpointers other than string and array pointers, and of course NULL ==NULL. Expressions of two different data types are always unequal.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -